如何删除EF代码第一个数据库中的儿童一对多的相关logging?
那么,我有一个一对多的相关模型:
public class Parent { public int Id { get; set; } public string Name { get; set; } public ICollection<Child> Children { get; set; } } public class Child { public int Id { get; set; } public string ChildName { get; set; } }
我想要做的是清除Parent.Children
并从数据库中删除相关的子实体。 我已经试过了:
数据库上下文类:
modelBuilder.Entity<Parent>() .HasMany(p => p.Children) .WithOptional() .WillCascadeOnDelete(true);
这工作正常,但我仍然在数据库中有Parent_Id = null
字段的冗余logging,当我这样做
parent.Children.Clear(); repository.InsertOrUpdate(parent);
在我的资料库类。 同样的行为也是当我做的时候:
modelBuilder.Entity<Parent>() .HasMany(pr => pr.Children) .WithOptional(ri => ri.Parent) .WillCascadeOnDelete(true);
在Child
类中有额外的Parent
属性
public class Child { ... public Parent Parent { get; set; } ... }
或者当我这样做
modelBuilder.Entity<Child>() .HasOptional(p => p.Parent) .WithMany(p => p.Children) .HasForeignKey(p => p.Parent_Id) .WillCascadeOnDelete(true);
在Child
类中增加了Parent_Id属性
public class Child { ... public int Parent_Id { get; set; } ... }
那么,怎样才能正确configuration级联删除呢? 或者,我应该如何删除这些子实体? 我认为这是偶然的任务,但我只是失去了一些东西。
级联删除在这里没有效果,因为您不删除parent
而只是调用InsertOrUpdate
。 正确的方法是逐个删除孩子,例如:
using (var context = new MyContext()) { var parent = context.Parents.Include(p => p.Children) .SingleOrDefault(p => p.Id == parentId); foreach (var child in parent.Children.ToList()) context.Children.Remove(child); context.SaveChanges(); }
在EF6中,执行操作的更快方法是…
context.Children.RemoveRange(parent.Children)
尝试改变
public virtual ICollection<Child> Children { get; set; }
因为需要虚拟来获得延迟加载。 如这里所解释的
我想你的parent.Children.clear没有工作,因为孩子还没有被加载
如果您的对象是自引用的,则可以使用下面的方法删除多对多和一对多的子对象。 只要记得随后调用db.SaveChanges():)
[HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(int id) { Object obj = this.db.Objects.Find(id); this.DeleteObjectAndChildren(obj); this.db.Objects.Remove(obj); this.db.SaveChanges(); return this.Json(new { success = true }); } /// <summary> /// This deletes an object and all children, but does not commit changes to the db. /// - MH @ 2016/08/15 14:42 /// </summary> /// <param name="parent"> /// The object. /// </param> private void DeleteObjectAndChildren(Object parent) { // Deletes One-to-Many Children if (parent.Things != null && parent.Things.Count > 0) { this.db.Things.RemoveRange(parent.Things); } // Deletes Self Referenced Children if (parent.Children != null && parent.Children.Count > 0) { foreach (var child in parent.Children) { this.DeleteObjectAndChildren(child); } this.db.Objects.RemoveRange(parent.Children); } }