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 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

时间: 2024-10-03 16:02:46

EF级联删除的相关文章

EF 级联删除

参考地址: https://www.cnblogs.com/HQFZ/p/4523761.html EF配置级联删除代码如下 modelBuilder.Entity<Doc>().HasMany(a => a.Lines).WithRequired(a => a.Doc).HasForeignKey(a => a.DocNo); //单头 modelBuilder.Entity<Line>().HasRequired(a => a.Doc).WithMany

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

      参考 EF里一对一.一对多.多对多关系的配置和级联删除 EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射

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

1.建立级联删除 Mr.E的级联删除并非数据库自带那个级联删除,而是Mr.E自带的,所以它能触发你C#里面编写的触发器. 首先,建立级联删除关系,如下图有两个表,UserInfo和UserDocument, UserDocument表依靠UserID字段,和UserInfo联系起来.现在我要实现,当UserInfo里面的数据删除时,自动删除UserDocument表里面UserID=UserInfo.id的那些数据,应该怎么做呢? 首先,双击UserInfo打开它的属性编辑器,点击[级联删除]设

sql server创建外键,子母表,级联删除。

级联删除. 最近建一个合同关系,在原有的资产平台上添加维保合同关系,维保合同问题, 需要在后面添加资产的维保合同,使用ef,该添加的冗余字段都已经添加上了,现在做这个,删除的时候只删了主表提示出问题,原来我没有在外键上选上  “级联删除”  属性 最终出现的结果就是要手动删了,这种做法是不对的!

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

目录 写在前面 文档与系列文章 一对多关系 一个例子 级联删除 级联保存 总结 写在前面 在前面的文章中,我们只使用了一个Customer类进行举例,而在客户.订单.产品中它们的关系,咱们并没有涉及,比如一个客户可以有一个或者多个订单,在数据库中变现为“主外键关系”,有时也喜欢称为“父子关系”.那么就让我们一起学习,在nhibernate中,是如何处理这种关系的吧? 文档与系列文章 [Nhibernate]体系结构 [NHibernate]ISessionFactory配置 [NHibernat

java:Oracle(级联删除,左右内外交叉自然连接,子查询,all,any,in)

1.级联删除: -- 级联删除:裁员,公司倒闭 -- 级联删除(cascade),设置为null(setnull),放任不管(No action) -- cascade:(以一对多为例)如果删除多的一方,一的一方不受任何影响,但是如果删除一的一方,多的一方所有对应数据全部被删除 select * from staff s inner join department d on d.id = s.department_id; delete from staff s where s.id = 1; d

MySQL中利用外键实现级联删除、更新

MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定在删除.更新父表时,对子表进行的相应操作,包括RESTRICT.NO ACTION.SET NULL和CASCADE.其中RESTRICT和NO ACTION相同,是指在子表有关联记录的情况下父表不能更新:CASCADE表示父表在更新或者删除时,更新或者删除子表对应记录:SET NULL则是表示父表在更新或者删除的时候,子表的对应字段被S

关于数据的级联删除和更新

两张表:“ProductCategory”,“Product”. 有一个需求是这样的:在删除某个ProductCategory 的时候,同时删除该Category的products. 在MySQL中利用外键实现级联删除 创建以下测试用数据库表: CREATE TABLE `roottb` ( `id` INT(11) UNSIGNED AUTO_INCREMENT NOT NULL, `data` VARCHAR(100) NOT NULL DEFAULT '', PRIMARY KEY (`i

数据库事务测试以及级联更新级联删除

数据库事务 start transaction; #开始事务 insert into gzb(gz)values(5000); insert into gzb(gz)values(6000); insert into gzb(gz)values(7000); insert into gzb(gz)values(8000); /*执行事务,并查看是否添加成功数据*/ commit; # commit数据,查看表中数据是否提交 rollback; #数据库回滚 级联更新,级联删除 主要通过两种方式