2012-01-25 3 views
12

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

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

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

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(); 

Но, я получаю ошибку:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

Я выбежала из идей о том, как удалить эти объекты. Есть идеи?

ответ

10

Каскад делеции концепция выглядит следующим образом:

При удалении 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

Вы не удалите BookFormats из базы данных, но вы удаляете отношения, таким образом, orpahning вашего 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

ну тогда я получаю сообщение об ошибке: Коллекция была изменена; операция перечисления может не выполняться. – Tony

+0

@ Тони, проверьте изменение на код. Не самый красивый способ, но выполняет свою работу. – bdparrish

14

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

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

Но это для EF 6.0

+1

Да. Это пример на RemoveRange.Но я отредактирую сообщение, чтобы не смутить некоторых. Благодарю. – Saykor

0

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

EF 7 не был выпущен. EF 6.1 - последняя стабильная версия. – MEMark

0

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

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