Entity Framework для удаления каскада - PullRequest
13 голосов
/ 25 января 2012

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

Книга 1 <---> * Книжные форматы

Я установил каскад удаления:

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. Когда изменение внесено в отношение, соответствующее свойство внешнего ключа установить нулевое значение. Если внешний ключ не поддерживает нулевые значения, новое отношение должно быть определено, свойство внешнего ключа должно быть назначено другое ненулевое значение, или не связанный объект должен быть Исключен.

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

Ответы [ 5 ]

17 голосов
/ 13 сентября 2013

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

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

Но это для EF 6.0

11 голосов
/ 25 января 2012

Каскадное удаление заключается в следующем:

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

foreach(var m in m.db.BookFormats.Where(f=>f.BookID == bookID))
{
    m.db.BookFormats.Remove(m);
}
m.db.SaveChanges();
4 голосов
/ 25 января 2012

Вы не удаляете BookFormats из базы данных, но удаляете связь, тем самым изменяя свой BookFormats и устанавливая для столбца BookID значение NULL .Каскад удаления, который вы поместили в базу данных, гласит: When I delete the Книга , 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.

0 голосов
/ 23 октября 2017

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

 var originalBook = m.db.Book.First(x => x.BookID == bookId);
 originalBook.BookFormats.Clear();
 db.Books.Remove(originalBook);
 m.db.SaveChanges();
0 голосов
/ 02 декабря 2013

Я использую 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();
...