首先在实体框架数据库中级联删除

Posted

技术标签:

【中文标题】首先在实体框架数据库中级联删除【英文标题】:Cascade delete in Entity Framework database first 【发布时间】:2019-01-10 17:49:16 【问题描述】:

我想在 ASP.NET 4.6.1 MVC 项目中进行 Cascade 删除,

这是数据库第一个项目,但级联删除不起作用。

我收到此错误:

操作失败:无法更改关系,因为一个或多个外键属性不可为空。 对关系进行更改时,相关的外键属性将设置为空值。 如果外键不支持...

我有两张桌子:

类别:

Category_ID
Category_Name

文章:

Article_ID
Article_Name
Article_Content
Category_ID   which is Foreign key

这是我要删除的代码:

var context = new DbContext();

Category category = context.Category.First(c => c.CategoryID == catID);

if (category != null)

    context.Category.Remove(category);
    context.SaveChanges();

【问题讨论】:

您需要向我们展示您的表格/代码,以便我们为您提供帮助。但是错误消息非常明显,您有一个不可为空的外键关系。所以如果你删除记录,外键关系就会失效。 我编辑了我的问题,但为什么级联删除不起作用 但是当我删除该类别时,我想删除与特定类别相关的所有文章!!! 不,是Database First,我的问题标题是Database First 你能改变你的数据库架构吗?喜欢为您的 FK 添加“ON DELETE CASCADE”吗? 【参考方案1】:

更新:对于 db 首先,转到应该级联的实体的属性,找到属性 End2 On Delete。将此设置为级联。

代码优先: 您可以在映射中定义要级联删除的关系。在您的数据上下文中,覆盖 OnModelCreating 并定义您的自定义映射。

我还没有测试过代码,但它应该看起来像这样:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Entity<Article>()
            .HasRequired(a => a.Category)
            .WithMany(c => c.Articles)
            .HasForeignKey(a => CategoryId)
            .WillCascadeOnDelete();

    

我们的想法是在您的映射上调用WillCascadeOnDelete()

https://msdn.microsoft.com/en-us/library/gg696319(v=vs.113).aspx

【讨论】:

该解决方案是数据库优先还是代码优先?问题首先指定 db。 这是代码优先。对于 db first,Visual Studio 设计器中有设置此属性的选项。我会更新答案 提问者在 EF Database-first 中要求级联删除,但答案是代码优先方法! @PureSilence 不!答案中的第一段是针对 db first 的。之后它还提供代码第一个答案 是的,你是对的!无论如何,这是一个很好的答案,感谢您注意到我!【参考方案2】:

如果您使用数据库优先的方法,首先您需要在数据库中为与 Cascade 的关系设置删除规则。

然后在您的程序中更新您的 EF 设计器。现在以下代码将删除 Category 对象及其所有文章:

if (dbContext.Entry(categoryObj).State == System.Data.Entity.EntityState.Detached)
                dbContext.Categories.Attach(categoryObj);

dbContext.Categories.Remove(categoryObj);

dbContext.SaveChanges();

【讨论】:

如何“设置数据库中与级联关系的删除规则”? 您可以在 ssms (SQL Server Management Studio) 中将 2 个表之间的当前外键约束设置为删除级联规则,如果您想通过 T-SQL 脚本执行此操作,那么首先您必须通过 ALTER 命令删除当前外键约束,然后: ALTER TABLE Article ADD CONSTRAINT Category_Article FOREIGN KEY (Category_ID) REFERENCES Category(Category_ID) ON DELETE CASCADE; 这可能是对答案的一个很好的补充

以上是关于首先在实体框架数据库中级联删除的主要内容,如果未能解决你的问题,请参考以下文章

sql中级联删除,级联更新是怎么理解的?

实体框架级联删除(继承)

实体框架核心级联删除错误

SQLite“在删除级联时”不在Qt中级联

实体框架级联删除 - FOREIGN KEY 约束

使用实体框架中的可选记录级联删除