如何在EF5中添加具有子实体但不更新这些子实体的实体

时间:2013-12-15 06:05:44

标签: entity-framework

我在Visual Studio 2012中使用EF5和POCO类以及.Net Framework 4.5。我有这样的父子关系:

public class Parent {
  [Key]
  public int Id {set; get}
  public string Name {set; get;}
  public int ChildId {set; get;}
  public virtual Child Child { get; set; }
}

public class Child {
      [Key]
      public int Id {set; get}
      public string Name {set; get;}
}

我在Web Api场景中使用EF5。客户端希望通过发送JSON来创建一个新的Parent:

{ 
Id: 0, 
Name:'Spock', 
ChildId: 42
}

javascript客户端不应该提供子对象,只需提供密钥。

但是,要做到这一点,这意味着在Web Api方法中,我必须读取Child实体并将其设置为Parent.Child,如下所示:

    parent.Child= (from child in db.Child where child.Id == parent.ChildId select child).FirstOrDefault();
    db.Parent.Attach(parent);
db.Entry(parent).State = System.Data.EntityState.Added;

如果我没有将parent.Child设置为与该键对应的实例,则EF会抛出异常:

ExceptionMessage=A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

我也尝试过像这样添加新的父对象:

db.Parent.Add(parent);

其中parent.Child为null,但随后Entity Framework生气并说:

ExceptionMessage=Cannot insert the value NULL into column 'Name', table 'MyDB.dbo.Child'; column does not allow nulls. INSERT fails.
The statement has been terminated.

有没有一种方法可以插入一个新的父行,而不必通过只设置其键来读取子节点的所有实例?我希望Parent POCO类在GET(读取)数据时填充子项,所以我想要那里的虚拟子属性,但我不希望客户端能够更新子项。我可以以某种方式告诉EF在添加或附加期间忽略子节点。在我的例子中,有一个孩子处于1:1的关系中,但可能存在许多和1:多种关系,所以这可能会变得非常难看,并且会受到很大的影响。

总之,我不希望EF创建子行或更新子行,如何阻止它以不涉及从数据库中读取和设置它们的方式更新子实体?< / p>

1 个答案:

答案 0 :(得分:0)

此关系中的“主要”实体是Child(子记录必须存在于数据库中才能添加父记录“。”依赖“实体是父级,只有在子实体在数据库中可用时才能添加该实体你的名字与这个名字并不相符......

子实体应该有父母导航属性

public ICollection<Parent> Parents { get; set; }

并且您需要将该导航的映射返回到父记录

HasMany(c => c.Parents).WithRequired().HasForeignKey(p => p.ChildId);

然后只要子记录已存在于数据库中,您就可以编写

db.Parents.Add(newParent);