C# 删除级联实体框架

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9005948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 05:33:56  来源:igfitidea点击:

Entity Framework on delete cascade

c#entity-frameworkforeign-keyscascading-deletes

提问by Tony

I have problem with deleting related rows in Entity Framework 4.1. I have tables with relations

我在删除实体框架 4.1 中的相关行时遇到问题。我有关系表

Book 1<--->* BookFormats

书 1<--->* BookFormats

I have set the on delete cascade:

我已经设置了删除级联:

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 属性

enter image description here

在此处输入图片说明

Then, I want to remove the all BokFormatsitems related to my Bookobject:

然后,我想删除BokFormats与我的Book对象相关的所有项目:

 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?

我没有关于如何删除这些对象的想法。有任何想法吗?

采纳答案by Vitaliy Kalinin

Cascade deletions concept is as follows:

级联删除的概念如下:

When you delete Bookfrom the DB all related BookFormatswill be deleted for you by SQL Server (please note that it doesn't matter how deletion of Bookwill be initiated via EF or raw SQL). Thus it has nothing to do with your task: "I want to delete all BookFormatsrelated to my Book". To accomplish it you need something like this:

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

回答by bdparrish

You are not deleting the BookFormatsfrom the database, but you are removing the relationship, thus orpahning your BookFormatsand setting the BookIDcolumn to NULL. The delete cascade you have put on the database says When I delete theBook, then delete all of theBookFormatsthat have aBookIDequal to mine.You are not deleting the book you are deleting the formats from the Book.

您不是BookFormats从数据库中删除,而是删除关系,从而孤立您BookFormats并将BookID列设置为NULL。您放在数据库中的删除级联显示When I delete theBook , then delete all of theBookFormats that have aBookIDequal to mine.您不是在删除您要从.csv 文件中删除格式的书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 方法。

回答by Saykor

You can use RemoveRange :

您可以使用 RemoveRange :

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

But this is for EF 6.0

但这是针对 EF 6.0

回答by prespic

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

回答by gbdavid

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