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 ...
随机推荐
- JAVA中的GC机制详解
优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只 ...
- 粒子动画Particleground.js
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JS高程1.javascript简介
1.javaScript诞生于1995年,最开始是为了处理以前由服务器端语言负责的一些诸如验证的操作. 2.一些名词: ECMA:European Computer Manufacturers Ass ...
- Tomcat部署记事
1.导入证书到jdk里 keytool -import -alias 证书名称 -file 证书地址 -keystore 导入位置 例:keytool -import -alias co3 -file ...
- Navigator对象、Screen对象
Navigator对象: Window对象的navigator属性引用的是包含浏览器厂商和版本信息的Navigator对象: Navigator对象集合:plugins[] 返回对 ...
- [web安全]Web应用漏洞攻击分析与防范
网站攻击主要分为以下几类: (1) sql注入攻击 SQL Injection:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.它是利 ...
- Java学习心得之 Linux下搭建Java环境
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Java学习心得之 Linux下搭建Java环境 1.前言2.JDK安装3.配置环境变量4. ...
- Day Tips:分布式缓存的删除和重建
遇到cacheHostInfo is null 错误时,必须将这台服务器上的实例删除重新创建 $instanceName ="SPDistributedCacheService Name=A ...
- 我的Android第三章:Android的组件介绍
小编摘录了Android文档介绍Android四大组件的基本内容,感觉文档的内容写的很详细所以小编将它写入了博客 Android 使用Java语言开发.Android SDK 工具编译代码-以及任意数 ...
- iOS学习路线
这个学习路线必须发布到首页候选区.这个学习路线必须发布到首页候选区.这个学习路线必须发布到首页候选区.这个学习路线必须发布到首页候选区.这个学习路线必须发布到首页候选区.这个学习路线必须发布到首页候选 ...