Подтвердить что ты не робот

Entity Framework при удалении каскада

У меня проблема с удалением связанных строк в Entity Framework 4.1. У меня есть таблицы с отношениями

Книга 1 < --- > * BookFormats

Я установил каскад on delete:

ALTER TABLE [dbo].[BookFormats]  WITH CHECK ADD  CONSTRAINT [FK_BookFormats_Book] 
FOREIGN KEY([BookID]) REFERENCES [dbo].[Book] ([BookID]) on delete cascade

Свойство EDMX

enter image description here

Затем я хочу удалить все элементы BokFormats, связанные с моим объектом Book:

 var originalBook = m.db.Book.First(x => x.BookID == bookId);
 originalBook.BookFormats.Clear();
 m.db.SaveChanges();

Но я получаю сообщение об ошибке:

Не удалось выполнить операцию: отношения не могут быть изменены, поскольку одно или несколько свойств внешнего ключа не имеют значения NULL. Когда изменение производится в отношении, связанное с ним свойство внешнего ключа установить на нулевое значение. Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, свойство внешнего ключа должно быть назначено другое ненулевое значение, или не связанный с ним объект должен быть удален.

У меня кончились идеи о том, как удалить эти объекты. Любые идеи?

4b9b3361

Ответ 1

Концепция делегирования каскадов такова:

Когда вы удаляете Book из БД, все связанные с ним BookFormats будут удалены для вас SQL Server (обратите внимание, что не имеет значения, как будет инициировано удаление Book через EF или raw SQL). Таким образом, это не имеет ничего общего с вашей задачей: "Я хочу удалить все BookFormats, связанные с моим Book". Для этого вам нужно что-то вроде этого:

foreach(var m in m.db.BookFormats.Where(f=>f.BookID == bookID))
{
    m.db.BookFormats.Remove(m);
}
m.db.SaveChanges();

Ответ 2

Вы можете использовать RemoveRange:

m.db.BookFormats.RemoveRange(originalBook.BookFormats);
m.db.SaveChanges();

Но это для EF 6.0

Ответ 3

Вы не удаляете BookFormats из базы данных, но вы удаляете взаимосвязь, таким образом, поддерживая свой BookFormats и устанавливая столбец BookID равным NULL. Каскад удаления, который вы положили в базу данных, говорит When I delete the Book , then delete all of the BookFormats that have a BookID equal to mine. Вы не удаляете книгу, которую вы удаляете из форматов из Book.

Вместо originalBook.BookFormats.Clear() у вас должно получиться что-то вроде этого...

List<int> idsToDelete = new List<int>();

foreach (BookFormat bf in originalBook.BookFormats)
{
    idsToDelete.Add(bf.ID);
}

foreach (int id in idsToDelete)
{
    BookFormat format = m.db.BookFormat.FirstOrDefault(x => x.ID == id);
    if (format != null)
    {
         m.db.DeleteBookFormat(format);
    }
}

m.db.SaveChanges();

Это должно быть что-то в этом роде. Я не имею права передо мной помнить, как EF создает метод удаления в EDMX.

Ответ 4

Я использую EF6, и это работает.

        var itemBinding = db.ItemBinding.Where(x => x.BindingToId == id) ;
        foreach (var ib in itemBinding)
        {
            db.Item.Remove(ib.Item);
            db.ItemBinding.Remove(ib);
        }
        db.SaveChanges();

Ответ 5

Я тестировал его в EF 6.1.3, и это должно работать нормально:

 var originalBook = m.db.Book.First(x => x.BookID == bookId);
 originalBook.BookFormats.Clear();
 db.Books.Remove(originalBook);
 m.db.SaveChanges();