引言
在主表中指定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.
总结
- 问题解决的时候我们应该从事由表及里,不能只停留在问题表面,而应该找出问题真实的原因。
- 在使用现有框架时,我们有必要把其基础原理搞清楚,也有必要把其使用场景搞清楚。(就像物理中许多定理中都有一个假设条件,而这个假设条件是这个定理成立的充分条件)
参考
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类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及, ...
随机推荐
-
【先定一个小目标】Windows下安装MongoDB 3.2
1.MongoDB 安装 官网提供了三个版本下载: - MongoDB for Windows 64-bit 适合 64 位的 Windows Server 2008 R2, Windows 7 , ...
-
持续集成配置-Teamcity
1.安装目录\buildagent\work\每个项目下一个文件夹\src下是源 目的: 2. 安装目录\buildagent\work\每个项目下一个文件夹\src下是源 目的是teamcity中配 ...
-
php 对多维数组排序array_multisort
php 对多维数组排序array_multisort 排序顺序标志: SORT_ASC - 按照上升顺序排序 SORT_DESC - 按照下降顺序排序 排序类型标志: SORT_REGULAR - 将 ...
-
CodeForces - 417E(随机数)
Square Table Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit ...
-
cms开发笔记2
1 创建数据库表 //配置文件CREATE TABLE IF NOT EXISTS `mc_config` ( `en_name` varchar(80) NOT NULL, `ch_name` va ...
-
asp.net mvc5 设置Area下的为启动页
只需修改App_Start文件夹下RouteConfig中RegisterRoutes方法 public static void RegisterRoutes(RouteCollection rout ...
-
数据采集工具flume
概述 flume是在2011年被首次引入到Cloudera的CDH3分发中,2011年6月,Cloudera将flume项目捐献给Apache基金会.2012年,flume项目从孵化器变成了*项目, ...
-
使用freemarker模板生成word文档
项目中最近用到这个东西,做下记录. 如下图,先准备好一个(office2003)word文档当做模板.文档中图片.姓名.性别和生日已经使用占位符代替,生成过程中将会根据实际情况进行替换. 然后将wor ...
-
cxgridchart饼状图
var VIEW:TcxGridDBChartView; Level:TcxGridLevel; Series:TcxGridDBChartSeries; begin View := cxGrid1. ...
-
Spring SpringBoot和SpringCloud的关系
Spring SpringBoot和SpringCloud的关系 Spring Cloud 是完全基于 Spring Boot 而开发,Spring Cloud 利用 Spring Boot 特性整合 ...