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