Entity framework 级联删除注意事项
版本:EF6.0.1 RC
一对多场景,在子对象映射中开启级联删除情况下,删除父对象将自动删除其下所有子对象,需要注意一些事项:
需要保证DbContext中已经加载了该父对象的所有子对象。
如果DbContext内未加载子对象将不级联删除子对象(请看示例代码1),
如DbContext只加载部分子对象也只级联删除这些子对象(遗漏删除未加载的子对象),(请看示例代码2)。
因此在查询父对象只应该使用Include("子对象属性名")查询(请看示例代码3)或者在DbContext另外把其下所有子对象查询出来(请看示例代码4),再进行对父对象的删除方可级联删除子对象。
示例代码:
这里只列出关键实体和过程代码,省去DbContext相关配置代码
//父类 public class Tb2Entity { public int Id { get; set; } public string Name { get; set; } public virtual IList<Item2Entity> Items { get; set; } } //子类 public class Item2Entity { public int Id { get; set; } public int? Pid { get; set; } public string Title { get; set; } public virtual Tb2Entity Parent { get; set; } }
示例代码1(不正确)
只删除了父对象遗漏删除子对象了
var i = 15; using (var db1 = new Db1Context("db conn string")) { var tb1 = new Tb2Entity { Id = i, Name = "n1", Items = new List<Item2Entity> { new Item2Entity{Id=1, Title="t1"}, new Item2Entity{Id=2, Title="t2"}, new Item2Entity{Id=3, Title="t3"} } }; db1.Set<Tb2Entity>().Add(tb1); db1.SaveChanges(); } Console.ReadKey(); using (var db1 = new Db1Context(Conns.db1)) { var tb1 = db1.Set<Tb2Entity>().Find(i); db1.Set<Tb2Entity>().Remove(tb1); db1.SaveChanges(); }
未例代码2(不正确)
只删除了父对象和部分子对象(遗漏删除id=3的子对象)
var i = 15; using (var db1 = new Db1Context(Conns.db1)) { var tb1 = new Tb2Entity { Id = i, Name = "n1", Items = new List<Item2Entity> { new Item2Entity{Id=1, Title="t1"}, new Item2Entity{Id=2, Title="t2"}, new Item2Entity{Id=3, Title="t3"} } }; db1.Set<Tb2Entity>().Add(tb1); db1.SaveChanges(); } Console.ReadKey(); using (var db1 = new Db1Context(Conns.db1)) { var tb1 = db1.Set<Tb2Entity>().Find(i); var item1 = db1.Set<Item2Entity>().Find(1); var item2 = db1.Set<Item2Entity>().Find(2); db1.Set<Tb2Entity>().Remove(tb1); db1.SaveChanges(); }
示例代码3(正确)
父对象连同子对象一起加载,级联删除时得以一起删除
var i = 15; using (var db1 = new Db1Context(Conns.db1)) { var tb1 = new Tb2Entity { Id = i, Name = "n1", Items = new List<Item2Entity> { new Item2Entity{Id=1, Title="t1"}, new Item2Entity{Id=2, Title="t2"}, new Item2Entity{Id=3, Title="t3"} } }; db1.Set<Tb2Entity>().Add(tb1); db1.SaveChanges(); } Console.ReadKey(); using (var db1 = new Db1Context(Conns.db1)) { var tb1 = db1.Set<Tb2Entity>() .Include(m => m.Items) //同时加载所有子对象 .Where(m => m.Id == i).Take(1).SingleOrDefault(); db1.Set<Tb2Entity>().Remove(tb1); db1.SaveChanges(); }
示例代码4(正确)
子对象通过延迟方式加载进来,级联删除时得以一起删除
var i = 15; using (var db1 = new Db1Context(Conns.db1)) { var tb1 = new Tb2Entity { Id = i, Name = "n1", Items = new List<Item2Entity> { new Item2Entity{Id=1, Title="t1"}, new Item2Entity{Id=2, Title="t2"}, new Item2Entity{Id=3, Title="t3"} } }; db1.Set<Tb2Entity>().Add(tb1); db1.SaveChanges(); } Console.ReadKey(); using (var db1 = new Db1Context(Conns.db1)) { var tb1 = db1.Set<Tb2Entity>().Find(i); //延迟方式加载所有子对象 if (tb1.Items != null) { } db1.Set<Tb2Entity>().Remove(tb1); db1.SaveChanges(); }
Entity framework 级联删除注意事项的更多相关文章
- Entity Framework 级联删除
为一对主从表增加级联删除功能 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.E ...
- SQL Server 与 Entity Framework 级联删除
SQL Server 级联设置我就不多说了,网上很多教程. 我想提的是 cycles or multiple cascade paths 的问题. 简单的说如果你的级联设置不是一个树型,而是一个带有循 ...
- EF级联删除
引言 在主表中指定Key,子表中指定Required后,并不会在数据库中生成级联删除的外键.那怎么才能使EF在数据中生成级联删除的外键? SQLServer数据库中级联删除功能配置界面: 上图 ...
- 【转】Entity Framework教程
转自:http://www.cnblogs.com/xray2005/category/189491.html Entity Framework系列文章导航 摘要: 本节集合了Entity Fra ...
- Entity Framework 简单增删改操作
前言 在 Entity Framework 简单查询操作 中主要是学习了在Entity Framework中的几种不同模式的查询操作,现在主要来学习一下简单的增加.删除.修改操作. 增加 在EF中添加 ...
- MVC5 Entity Framework学习之实现主要的CRUD功能
在上一篇文章中,我们使用Entity Framework 和SQL Server LocalDB创建了一个MVC应用程序,并使用它来存储和显示数据.在这篇文章中,你将对由 MVC框架自己主动创建的CR ...
- Entity Framework Code First级联删除
如果我们要到一对主从表增加级联删除,则要在主表中的引用属性上增加Required关键字,如: public class Destination { public int DestinationId { ...
- Entity Framework Code First级联删除(转)
使用Data Annotations: 如果我们要到一对主从表增加级联删除,则要在主表中的引用属性上增加Required关键字,如: public class Destination { public ...
- Entity Framework Core系列之DbContext(删除)
上一篇我们介绍了Entity Framework Core系列之DbContext(修改),这一篇我们介绍下删除数据 修改实体的方法取决于context是否正在跟踪需要删除的实体. 下面的示例中con ...
随机推荐
- Spring4学习笔记2-配置Bean
1.配置bean 配置形式:Xml和注解方式 Bean的配置方式:通过全类名(反射).工厂.FactoryBean 1.1 id必须唯一 2 Spring提供两种类型的IOC容器的实现 BeanFac ...
- C#实现jQuery的方法连缀
jQuery的方法连缀使用起来非常方便,可以简化语句,让代码变得清晰简洁.那C#的类方法能不能也实现类似的功能呢?基于这样的疑惑,研究了一下jQuery的源代码,发现就是需要方法连缀的函数方法最后返回 ...
- JS判断是否是数字
function isNumber(value) { var patrn = /^[0-9]*$/; if (patrn.exec(value) == null || value == "& ...
- Error: Error setting TTL index on collection : sessions
Error: Error setting TTL index on collection : sessions 一.步骤一: 这个问题一般是直接升级 mongodb和connect-mongo的版本为 ...
- ae
根据属性提取要素(利用GP) http://blog.csdn.net/ewyetc/article/details/6746728
- Python 操作 MySQL 之 pysql 与 ORM(转载)
本文针对 Python 操作 MySQL 主要使用的两种方式讲解: 原生模块 pymsql ORM框架 SQLAchemy 本章内容: pymsql 执行 sql 增\删\改\查 语句 pymsql ...
- Oracle12C相关
1.jar包安装到MVN本地库 mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.1 ...
- Android 常用抓包工具介绍之Charles
➠更多技术干货请戳:听云博客 Charles是一款抓包修改工具,相比起TcpDump,charles具有界面简单直观,易于上手,数据请求控制容易,修改简单,抓取数据的开始暂停方便等等优势!前面介绍了如 ...
- 【代码笔记】iOS-平面化的饼图
一,效果图. 二,工程图. 三,代码. RootViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additi ...
- 【VLC-Android】LibVLC API简介(相当于VLC的MediaPlayer)
前言 学新东西API很重要,这里抛砖引玉整理了一下,欢迎反馈! 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: http://over14 ...