Обновление внешнего ключа при программном удалении

#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? Вероятно, это не так, поэтому вы получаете сообщение об ошибке. Здесь у вас есть два подхода:

  1. Создайте фиктивную «удаленную» категорию с Id = 0 (я лично предпочитаю -1 для этих вещей), обновите ее при мягком удалении
  2. Установите CategoryId значение NULL , если поле позволяет NULLs . Это означает, что для этой записи нет никакого отношения к категории.

Ответ №2:

На вашем месте это были бы следующие шаги

  1. Проверьте, есть ли Any фильмы с тем же идентификатором категории, но с другим идентификатором, чем у удаляемого фильма
  2. Если это так, то удалите только фильм
  3. Если нет, то удалите категорию и каскад (если это невозможно, сначала удалите фильм, а затем категорию)

Существует также проблема параллелизма. Что делать, если есть два фильма одной категории, и они удаляются одновременно? Это может привести к проблеме, заключающейся в том, что фильмы удаляются в разных потоках, и оба потока проверяют, есть ли какие-либо другие фильмы, и для каждого фильма другой фильм найден до его удаления. Чтобы справиться с этой ситуацией, я предлагаю создать какую-то очередь удаления фильмов, и когда фильм должен быть удален, он войдет в очередь. Этот последовательный способ удаления фильмов устранит проблему параллелизма.