引言

 

 

在主表中指定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 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

EF级联删除的更多相关文章

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

    本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个PersonPhoto类,表示用户照片类 /// < ...

  2. EF——一对一、一对多、多对多关系的配置和级联删除 04(转)

    EF里一对一.一对多.多对多关系的配置和级联删除   本章节开始了解EF的各种关系.如果你对EF里实体间的各种关系还不是很熟悉,可以看看我的思路,能帮你更快的理解. I.实体间一对一的关系 添加一个P ...

  3. 15.翻译系列:EF 6中的级联删除【EF 6 Code-First 系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/cascade-delete-in-code-first.aspx EF 6 Code- ...

  4. (26)ASP.NET Core EF保存(基本保存、保存相关数据、级联删除、使用事务)

    1.简介 每个上下文实例都有一个ChangeTracker,它负责跟踪需要写入数据库的更改.更改实体类的实例时,这些更改会记录在ChangeTracker中,然后在调用SaveChanges时会被写入 ...

  5. .Net开源数据库设计工具Mr.E For Linq (EF 6.1) 教程(二)级联删除和触发器

    1.建立级联删除 Mr.E的级联删除并非数据库自带那个级联删除,而是Mr.E自带的,所以它能触发你C#里面编写的触发器. 首先,建立级联删除关系,如下图有两个表,UserInfo和UserDocume ...

  6. EF 主键自增、级联删除

    一.主键自增 1.设置数据库中,主键自增 2.设置VS中Model1.edmx

  7. EF Code-First 学习之旅 级联删除

    级联删除是当删除主记录的时候会自动删除依赖的记录或者设置外键属性为null public class Student { public Student() { } public int Student ...

  8. EF Core的级联删除

    级联删除由DeleteBehavior的枚举值来设置: 行为名称 对内存中的依赖项/子项的影响 对数据库中的依赖项/子项的影响 Cascade 删除实体 删除实体 ClientSetNull 外键属性 ...

  9. [NHibernate]一对多关系(级联删除,级联添加)

    目录 写在前面 文档与系列文章 一对多关系 一个例子 级联删除 级联保存 总结 写在前面 在前面的文章中,我们只使用了一个Customer类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及, ...

随机推荐

  1. LINQ to SQL语句(16)之对象标识

    对象标识 运行库中的对象具有唯一标识.引用同一对象的两个变量实际上是引用此对象的同一实例.你更改一个变量后,可以通过另一个变量看到这些更改. 关系数据库表中的行不具有唯一标识.由于每一行都具有唯一的主 ...

  2. 初入网络系列笔记(1)TCP/IP基础

    一.借鉴说明,本博文借鉴以下博文 1.BlueTzar,TCP/IP四层模型, http://www.cnblogs.com/BlueTzar/articles/811160.html 2.叶剑峰,漫 ...

  3. processModel与ASP.NET进程模型

    配置 Microsoft Internet 信息服务 (IIS) Web 服务器上的 ASP.NET 进程模型设置.其作用是配置IIS或IIS中的应用程序池(IIS7及以后版本)的安全性,性能,健壮性 ...

  4. 【转】窗口之间的主从关系与Z-Order

    原文链接:http://www.cnblogs.com/dhatbj/p/3288152.html 说明:这是本人2008年写的一篇旧文,从未公开发表过.其中除了一小段描述Window Mobile平 ...

  5. eclipse js 报错解决办法

    最近项目中的js一直红叉叉,本人本来就是那种看见回收站有东西想清理的那种强迫症患者, 所以对于这种红叉叉更是心烦.这个我已经忍了好久了.今天 见这哥们犀利的解决了这个eclipes的bug.很是激动, ...

  6. tomcat 7 WARNING: A context path must either be an empty string or start with a '/' and do not end with a '/'. The path [/] does not meet these criteria and has been changed to []

    tomcat 7 WARNING: A context path must either be an empty string or start with a '/' and do not end w ...

  7. JAVA理解逻辑程序的书上全部重要的习题

    今天随便翻翻看以前学过JAVA理解逻辑程序的书上全部练习,为了一些刚学的学弟学妹,所以呢就把这些作为共享了. 希望对初学的学弟学妹有所帮助! 例子:升级“我行我素购物管理系统”,实现购物结算功能 代码 ...

  8. $(function) ready onload 等区别

    新手接触javascript.jquery的时候不可避免的要接触题目所标识的相关内容,反复看过几次一到用的时候总是不踏实,写文以记之. 符号“$”是jquery对象(个人这样理解,拥有函数的用法).接 ...

  9. ASP.NET Mvc实用框架(一)Ioc、仓储模式和单元工作模式

    Framework.EF 首先看一下这个类库: Extended文件夹存放的是EntityFramework.Extensions这个插件的源代码,没有别的原因,就是本人觉得这个插件挺好的,每次省的下 ...

  10. SharePoint 快捷获取列表栏内部名称

    在列表设置页面点击浏览器书签获取列表字段内部名称,使用效果如下图: 如何使用: 修改浏览器上任意书签的url地址为以下代码,注意:代码中不能有换行符 javascript:(function(){va ...