代码之家  ›  专栏  ›  技术社区  ›  Nathan Taylor

实体框架-清除子集合

  •  25
  • Nathan Taylor  · 技术社区  · 16 年前

    我在实体框架方面遇到了一个有趣的问题,根据我用来解决这个问题的代码,我怀疑我的解决方案不太理想。我在表a和表B之间有一对多的关系,其中表B中的实体引用了表a。我有一个场景,我想同时删除TableA中一行的所有子行,我认为这可以通过简单地清除集合来实现:

    Entity.Children.Clear()
    

    不幸的是,当我试图保存更改时,这会导致外键冲突。

    从关联数据库中删除 “FK_EntityB_EntityA”。以基数 还必须添加或删除。

    我提出的解决方案是通过实体上下文的DeleteObject()手动删除对象,但我知道我使用的这个逻辑肯定是错误的。

    while (collection.Any())
        Entities.DeleteObject(collection.First());
    

    3 回复  |  直到 16 年前
        1
  •  21
  •   Craig Stuntz    16 年前

    Clear() 移除 对于实体,而不是实体本身。

    如果你打算这样做的话 同样的操作,你可以处理 AssociationChanged :

    Entity.Children.AssociationChanged += 
        new CollectionChangeEventHandler(EntityChildrenChanged);
    Entity.Children.Clear();            
    
        private void EntityChildrenChanged(object sender,
            CollectionChangeEventArgs e)
        {
            // Check for a related reference being removed. 
            if (e.Action == CollectionChangeAction.Remove)
            {
                Context.DeleteObject(e.Element);
            }
        }
    

        2
  •  6
  •   syned    14 年前

    您可以在父实体和子实体之间创建标识关系,当您从父实体集合中删除子实体时,EF将删除该子实体。

        public class Parent
        {
          public int ParentId {get;set;}
          public ICollection<Child> Children {get;set;}
        }
    
        public class Child
        {          
          public int ChildId {get;set;}
          public int ParentId {get;set;}
        }
    

    映射配置:

        modelBuilder.Entity<Child>().HasKey(x => new { x.ChildId, x.ParentId });
        modelBuilder.Entity<Parent>().HasMany(x => x.Children).WithRequired().HasForeignKey(x => x.ParentId);
    
        3
  •  6
  •   Emilio Weba    10 年前

    技巧:在设置父级和子级之间的关系时,必须在子级上创建一个“复合”键。这样,当您告诉父级删除1个或其所有子级时,相关记录实际上将从数据库中删除。

    modelBuilder.Entity<Child>().HasKey(t => new { t.ParentId, t.ChildId });
    

    然后,要删除相关子项,请执行以下操作:

    var parent = _context.Parents.SingleOrDefault(p => p.ParentId == parentId);
    
    var childToRemove = parent.Children.First(); // Change the logic 
    parent.Children.Remove(childToRemove);
    
    // you can delete all children if you want 
    // parent.Children.Clear();
    
    _context.SaveChanges();
    

    完成!