用一对多去除孤儿

时间:2013-12-21 16:52:35

标签: c# entity-framework

我有以下代码:

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

public class Child
{          
  public int ChildId {get;set;}
  public Parent Parent {get;set;}
}

它被EF映射为一对多而无需任何额外的努力。当我用新集合替换Children时(另外3个项目)我在子表中有旧的孤儿实体,如下所示:

Id | Parent_Id
1     NULL       <-- orphan
2     NULL       <-- orphan
3     NULL       <-- orphan
4       1        <-- new
5       1        <-- new
6       1        <-- new

我希望明确地找出关系来消除它们:

modelBuilder.Entity<Child>().HasKey(x => new { x.ChildId, x.ParentId });
modelBuilder.Entity<Parent>().HasMany(x => x.Children).WithRequired().HasForeignKey(x => x.ParentId);

但是我没有孩子的ParentId属性。我只有“父”直接指向父实体。如果我试试

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

我收到错误消息:

属性...不能用作实体的关键属性...因为属性类型不是有效的键类型

有没有办法删除所有不必要的孤儿?

2 个答案:

答案 0 :(得分:1)

据我所知,为了识别关系,您需要父母主键作为孩子主键的一部分。然后,EF将允许您从收集中删除该子项并将其删除。

只是让导航属性不起作用。识别关系是数据库级别的概念,因此需要公开的主键ID

请参阅我关于该主题的问题here

答案 1 :(得分:1)

在我的应用程序中,我有一个类似的模型。然而,我没有去除孤儿,而是生产它们。如果我想删除一些子对象,我会按以下方式执行:

//This line attaches a parent object to the session. EF will start monitoring it. 
Entry(parent).State = EntityState.Modified;

//This code is responsible for finding children to delete.
foreach (var child in parent.Children.Where(ch => ch.Deleted))
    //This line says EF that given child should be removed.
    //This line also causes that an object will be removed from Children collection.
    Entry(child).State = EntityState.Deleted;

SaveChanges();

已删除是我要设置为 true 的属性,如果我要删除对象。