#c# #sql #foreign-keys
#c# #sql #внешние ключи
Вопрос:
В моей базе данных есть 2 строки. Category
и Movie
.
Когда я выполняю мягкое удаление Movie
, я хочу удалить ссылку FK на Category
.
У меня есть метод удаления, который выглядит следующим образом:
public override async Task DeleteAsync(long id, bool permanent = false)
{
await DbFactory.ExecAsync(async (db) =>
{
if (permanent)
{
await db.DeleteAsync<Movie>(x => x.Id == id);
}
else
{
await db.UpdateAsync<Movie>(new { Deleted = true, CategoryId = 0 }, x => x.Id == id);
}
});
}
Но он выдает исключение FK, когда я пытаюсь обновить CategoryId
Как я могу это сделать? Я хочу иметь возможность мягко удалять a Movie
, а затем, только если в категории нет ссылок, можно удалить категорию.
Ответ №1:
Существует ли запись с CategoryId
= 0? Вероятно, это не так, поэтому вы получаете сообщение об ошибке. Здесь у вас есть два подхода:
- Создайте фиктивную «удаленную» категорию с Id = 0 (я лично предпочитаю -1 для этих вещей), обновите ее при мягком удалении
- Установите
CategoryId
значениеNULL
, если поле позволяетNULLs
. Это означает, что для этой записи нет никакого отношения к категории.
Ответ №2:
На вашем месте это были бы следующие шаги
- Проверьте, есть ли
Any
фильмы с тем же идентификатором категории, но с другим идентификатором, чем у удаляемого фильма - Если это так, то удалите только фильм
- Если нет, то удалите категорию и каскад (если это невозможно, сначала удалите фильм, а затем категорию)
Существует также проблема параллелизма. Что делать, если есть два фильма одной категории, и они удаляются одновременно? Это может привести к проблеме, заключающейся в том, что фильмы удаляются в разных потоках, и оба потока проверяют, есть ли какие-либо другие фильмы, и для каждого фильма другой фильм найден до его удаления. Чтобы справиться с этой ситуацией, я предлагаю создать какую-то очередь удаления фильмов, и когда фильм должен быть удален, он войдет в очередь. Этот последовательный способ удаления фильмов устранит проблему параллелизма.