版本: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 级联删除注意事项的更多相关文章

  1. Entity Framework 级联删除

    为一对主从表增加级联删除功能 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.E ...

  2. SQL Server 与 Entity Framework 级联删除

    SQL Server 级联设置我就不多说了,网上很多教程. 我想提的是 cycles or multiple cascade paths 的问题. 简单的说如果你的级联设置不是一个树型,而是一个带有循 ...

  3. EF级联删除

    引言     在主表中指定Key,子表中指定Required后,并不会在数据库中生成级联删除的外键.那怎么才能使EF在数据中生成级联删除的外键? SQLServer数据库中级联删除功能配置界面: 上图 ...

  4. 【转】Entity Framework教程

    转自:http://www.cnblogs.com/xray2005/category/189491.html   Entity Framework系列文章导航 摘要: 本节集合了Entity Fra ...

  5. Entity Framework 简单增删改操作

    前言 在 Entity Framework 简单查询操作 中主要是学习了在Entity Framework中的几种不同模式的查询操作,现在主要来学习一下简单的增加.删除.修改操作. 增加 在EF中添加 ...

  6. MVC5 Entity Framework学习之实现主要的CRUD功能

    在上一篇文章中,我们使用Entity Framework 和SQL Server LocalDB创建了一个MVC应用程序,并使用它来存储和显示数据.在这篇文章中,你将对由 MVC框架自己主动创建的CR ...

  7. Entity Framework Code First级联删除

    如果我们要到一对主从表增加级联删除,则要在主表中的引用属性上增加Required关键字,如: public class Destination { public int DestinationId { ...

  8. Entity Framework Code First级联删除(转)

    使用Data Annotations: 如果我们要到一对主从表增加级联删除,则要在主表中的引用属性上增加Required关键字,如: public class Destination { public ...

  9. Entity Framework Core系列之DbContext(删除)

    上一篇我们介绍了Entity Framework Core系列之DbContext(修改),这一篇我们介绍下删除数据 修改实体的方法取决于context是否正在跟踪需要删除的实体. 下面的示例中con ...

随机推荐

  1. 为jQuery-easyui的tab组件添加右键菜单功能

    加入了右击TAB选项卡时显示关闭的上下文菜单 具体实现代码: 右键菜单 HTML: <div id="mm" class="easyui-menu" st ...

  2. JavaScript学习(3):函数式编程

    在这篇文章里,我们讨论函数式编程. 什么是函数式编程?根据百度百科的描述,“函数式编程是种编程典范,它将电脑运算视为函数的计算.函数编程语言最重要的基础是 λ 演算(lambda calculus). ...

  3. HTML5 模拟现实物理效果,感受 Web 技术魅力

    Ball Pool 是一个基于 HTML5 技术的实验,模拟现实物理效果,让你在 Web 中感受自然物体的运动.玩法介绍:可以随意拖动圆球.点击页面背景.晃动浏览器.双击页面背景或者按住鼠标左键,有不 ...

  4. ArcGIS Server 标准版和高级版在Web3D的区别

  5. tomcat通过socket连接MySQL,不再占用服务端口【linux】

    MySQL连接方式的说明 http://icbm.iteye.com/blog/1840673 MySQL除了最常见的TCP连接方式外,还提供SOCKET(LINUX默认连接方式).PIPE和SHAR ...

  6. 闲聊桌面应用开发[Win16->Win32->ATL/WTL/MFC->WinForm->WPF/Silverlight/WinRT]

    闲来无聊,正好小组人员讨论到桌面的开发,那把笔者接触的WIndows平台下的几个主要的发展过程聊一聊. 主要从概述,参考资料,图书等几个方面说起. 所有的界面开发都会涉及如下的几个方面的内容: v 控 ...

  7. LeakCanary中英文文档+使用例子

    Android 开源界最伟(jian)大(zhi)高(kai)效(gua)的公司 Square 又向业界投下一颗重磅炸弹.推出了一个叫 LeakCanary 的玩意儿,可以通过简单粗暴的方式来让开发者 ...

  8. 操作系统开发系列—13.d.多进程 ●

    进程此时不仅是在运行而已,它可以随时被中断,可以在中断处理程序完成之后被恢复.进程此时已经有了两种状态:运行和睡眠.我们已经具备了处理多个进程的能力,只需要让其中一个进程处在运行态,其余进程处在睡眠态 ...

  9. iOS 在xib或storyboard里为控件添加圆角、外框和外框颜色

    如果要在xib和storyboard里为控件添加圆角和外框宽度,只要这样做就可以 layer.borderWidth     设置外框宽度属性 layer.cornerRadius    设置圆角属性 ...

  10. 网站错误记录:Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool.

    今天看公司项目的错误日志文件,发现日志文件都是记录的这个错误. 经过网站查找,发现英文翻译是: 译:超时,与连接池的连接时间已过.这种情况发生是因为连接池在使用和最大连接池数目已满 通过翻译,可以看出 ...