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();
            }

  

你可能感兴趣的:(framework)