EF级联删除
引言
在主表中指定Key,子表中指定Required后,并不会在数据库中生成级联删除的外键。那怎么才能使EF在数据中生成级联删除的外键?
SQLServer数据库中级联删除功能配置界面:

上图中显示只用[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 DELETEon 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.
总结
- 问题解决的时候我们应该从事由表及里,不能只停留在问题表面,而应该找出问题真实的原因。
- 在使用现有框架时,我们有必要把其基础原理搞清楚,也有必要把其使用场景搞清楚。(就像物理中许多定理中都有一个假设条件,而这个假设条件是这个定理成立的充分条件)
参考
EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射
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
EF级联删除的更多相关文章
- EF里一对一、一对多、多对多关系的配置和级联删除
本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个PersonPhoto类,表示用户照片类 /// < ...
- EF——一对一、一对多、多对多关系的配置和级联删除 04(转)
EF里一对一.一对多.多对多关系的配置和级联删除 本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个P ...
- 15.翻译系列:EF 6中的级联删除【EF 6 Code-First 系列】
原文链接:https://www.entityframeworktutorial.net/code-first/cascade-delete-in-code-first.aspx EF 6 Code- ...
- (26)ASP.NET Core EF保存(基本保存、保存相关数据、级联删除、使用事务)
1.简介 每个上下文实例都有一个ChangeTracker,它负责跟踪需要写入数据库的更改.更改实体类的实例时,这些更改会记录在ChangeTracker中,然后在调用SaveChanges时会被写入 ...
- .Net开源数据库设计工具Mr.E For Linq (EF 6.1) 教程(二)级联删除和触发器
1.建立级联删除 Mr.E的级联删除并非数据库自带那个级联删除,而是Mr.E自带的,所以它能触发你C#里面编写的触发器. 首先,建立级联删除关系,如下图有两个表,UserInfo和UserDocume ...
- EF 主键自增、级联删除
一.主键自增 1.设置数据库中,主键自增 2.设置VS中Model1.edmx
- EF Code-First 学习之旅 级联删除
级联删除是当删除主记录的时候会自动删除依赖的记录或者设置外键属性为null public class Student { public Student() { } public int Student ...
- EF Core的级联删除
级联删除由DeleteBehavior的枚举值来设置: 行为名称 对内存中的依赖项/子项的影响 对数据库中的依赖项/子项的影响 Cascade 删除实体 删除实体 ClientSetNull 外键属性 ...
- [NHibernate]一对多关系(级联删除,级联添加)
目录 写在前面 文档与系列文章 一对多关系 一个例子 级联删除 级联保存 总结 写在前面 在前面的文章中,我们只使用了一个Customer类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及, ...
随机推荐
- javascript设计模式实践之职责链--具有百叶窗切换图片效果的JQuery插件(三)
在上一篇<javascript设计模式实践之模板方法--具有百叶窗切换图片效果的JQuery插件(二)>里,通过采用模板方法模式完成了切换效果对象的构建编写. 接下来就是完成各效果对象的调 ...
- 各种类型转换为字符串类型(ToString())
更详细请参考:http://blog.csdn.net/wanzhuan2010/article/details/8478904 // C 货币 2.5.ToString("C") ...
- Xamarin.ios引用第三方SDK
引言 诚然,Xamarin是个优秀的跨平台解决方案,但毕竟还是不能将Native中所有的方法都直接实现.诸如各种第三方库,也都只有java/oc原生版本的SDK,无法直接拿过来直接使用.但,不能直接拿 ...
- Cursor的用法
文章主要来自于::::http://www.cnblogs.com/TerryBlog/archive/2010/07/05/1771459.html 主要为了自己学习方便,侵删!!!! 使用过 SQ ...
- php实现设计模式之 工厂方法模式
<?php /* * *工厂方法模式,创建型模式 定义一个用于创建对象的工厂接口,让子类决定实例化哪一个类.Factory Method使用一个类的实例化延迟到其子类 * * 四个角色: * 工 ...
- ABP导航源码分析
按步骤看: 1,在Global.asax中执行: base.Application_Start(sender, e); 2,在AbpWebApplication类的Application_Start( ...
- HttpClient在HTTP协议接口测试中的使用
TTP协议的接口测试中,使用到最多的就是GET请求与POST请求,其中POST请求有FORM参数提交请求与RAW请求,下面我将结合HttpClient来实现一下这三种形式: 一.GET请求: GET请 ...
- #9.1课堂总结#JS基础(二)
在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只 ...
- iOS中延时执行的几种方式的比较和汇总
本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.perf ...
- SharePoint Conference 2014 Keynote
让我们来看看今年 SharePoint Conference 2014 的重点都是些什么内容.虽然 BI 那个视频很有趣儿,但是 keynote 可能更重要一些,所以,先研究 keynote. 概括来 ...