EF级联删除

本文深入探讨了在Entity Framework中配置级联删除的详细步骤与注意事项,包括如何通过设置关系属性来确保父对象删除时自动级联删除其所有子对象,以及在不同场景下实现级联删除的正确做法。文章强调了理解和应用级联删除功能的基础原理对于避免常见错误的重要性。
摘要由CSDN通过智能技术生成

引言

 

 

在主表中指定Key,子表中指定Required后,并不会在数据库中生成级联删除的外键。那怎么才能使EF在数据中生成级联删除的外键?

SQLServer数据库中级联删除功能配置界面:

image

上图中显示只用[required]特性后生成的外键没有级联删除动作。

 

看似正确的解决方案。(治标的处理方式)

版本:EF6.0.1 RC

一对多场景,在子对象映射中开启级联删除情况下,删除父对象将自动删除其下所有子对象,需要注意一些事项:

 √ 需要保证DbContext中已经加载了该父对象的所有子对象。

 X  如果DbContext内未加载子对象将不级联删除子对象,

 X 如DbContext只加载部分子对象也只级联删除这些子对象。

因此在查询父对象只应该使用Include("子对象属性名")查询(请看示例代码3)或者在DbContext另外把其下所有子对象查询出来(请看示例代码4),再进行对父对象的删除方可级联删除子对象。

但注意以上所述情况只适用于关联子项比较少的情况,数据量少的演示测试Demo可以,工作中应该杜绝该类解决方案的出现。

 

真正的解决方案(治本的处理方式)

 

以下摘自是EntityFrameWork 官网原文

----------------------------------------------------------------

You can configure cascade delete on a relationship by using the WillCascadeOnDelete method. If a foreign key on the dependent entity is not nullable, then Code First sets cascade delete on the relationship. If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set to null.

You can remove these cascade delete conventions by using:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()

The following code configures the relationship to be required and then disables cascade delete.

modelBuilder.Entity<Course>()
    .HasRequired(t => t.Department)
    .WithMany(t => t.Courses)
    .HasForeignKey(d => d.DepartmentID)
    .WillCascadeOnDelete(false);

 

EF到底怎么搞定级联删除

 

Setting Cascade on a relation in EF designer instructs EF to execute DELETE statement for each loaded realated entity. It doesn't say anything about ON CASCADE DELETE in the database.

Setting Cascade deletion when using EF needs two steps:

  • Set Cascade on relation in EF designer. This instruct context that all loaded related entitiesmust be deleted prior to deletion of the parent entity. If this doesn't happen EF will throw exception because internal state will detect that loaded childs are not related to any existing parent entity even the relation is required. I'm not sure if this happens before execution of delete statement of the parent entity or after but there is no difference. EF doesn't reload related entities after executing modifications so it simply doesn't know about cascade deletes triggered in the database.
  • Set ON CASCADE DELETE on relation in database. This will instruct SQL to delete all related records which were not loaded to context in the time of deleting the parent.

The implementation of cascade deletes in EF is strange and quite inefficient but this is how it behaves and if you want to use it, you must modify your application to behaves correctly in this scenario.

 

 

总结

  1. 问题解决的时候我们应该从事由表及里,不能只停留在问题表面,而应该找出问题真实的原因。
  2. 在使用现有框架时,我们有必要把其基础原理搞清楚,也有必要把其使用场景搞清楚。(就像物理中许多定理中都有一个假设条件,而这个假设条件是这个定理成立的充分条件)

 

参考

EF里一对一、一对多、多对多关系的配置和级联删除

Entity framework 级联删除注意事项

EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射

Enabling Cascade Delete

Entity Framework 4.3 delete cascade with code first (Poco)

Cascading Deletes in LINQ to SQL

Cascading deletes with Entity Framework - Related entities deleted by EF

转载于:https://www.cnblogs.com/HQFZ/p/4523761.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值