简体   繁体   English

删除级联上的实体框架

[英]Entity Framework on delete cascade

I have problem with deleting related rows in Entity Framework 4.1. 我在删除实体框架4.1中的相关行时遇到问题。 I have tables with relations 我有关系的桌子

Book 1<--->* BookFormats 书1 <---> *书格式

I have set the on delete cascade: 我已经设置了on delete级联:

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

The EDMX property EDMX属性

在此处输入图片说明

Then, I want to remove the all BokFormats items related to my Book object: 然后,我要删除与Book对象相关的所有BokFormats项目:

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

But, I get the error: 但是,我得到了错误:

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. 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

I ran out of ideas on how to delete these objects. 我没有关于如何删除这些对象的想法。 Any ideas? 有任何想法吗?

You can use RemoveRange : 您可以使用RemoveRange:

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

But this is for EF 6.0 但这是针对EF 6.0

Cascade deletions concept is as follows: 级联删除的概念如下:

When you delete Book from the DB all related BookFormats will be deleted for you by SQL Server (please note that it doesn't matter how deletion of Book will be initiated via EF or raw SQL). 当您从数据库中删除Book ,SQL Server会为您删除所有相关的BookFormats (请注意,如何通过EF或原始SQL删除Book并不重要)。 Thus it has nothing to do with your task: "I want to delete all BookFormats related to my Book ". 因此,它与您的任务无关:“我想删除与我的Book有关的所有BookFormats ”。 To accomplish it you need something like this: 要实现它,您需要这样的事情:

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

You are not deleting the BookFormats from the database, but you are removing the relationship, thus orpahning your BookFormats and setting the BookID column to NULL . 您不是要从数据库中删除BookFormats ,而是要删除关系,从而使您的BookFormats并将BookID列设置为NULL The delete cascade you have put on the database says When I delete the Book , then delete all of the BookFormats that have a BookID equal to mine. 您放在数据库中的删除级联显示“ When I delete the Book时, then delete all of the BookID equal to mine. that have a BookFormat” equal to mine. You are not deleting the book you are deleting the formats from the Book . 您不是要删除图书,而是要从Book中删除格式。

Instead of originalBook.BookFormats.Clear() you should have something like this... 而不是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();

It should be something along those lines. 应该遵循这些原则。 I don't have it right in front of me to remember how EF constructs the delete method in the EDMX. 我想不起来EF是如何在EDMX中构造delete方法的。

I've tested it in EF 6.1.3 and this should work fine: 我已经在EF 6.1.3中对其进行了测试,它应该可以正常工作:

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

I use EF6 and this works. 我使用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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM