我已经在数据库中插入了一些父记录。现在我想添加一些子记录。为此,我按照以下步骤操作:
问题是,当我这样做时,EF插入一个New Parent,然后添加一个外键指向新插入的父项,而不是只插入映射到已存在父项的子项。我还在保存子项时检查了父项的主键,它确实存在于数据库中。
请注意,我正在为Parent和Child使用数据库生成的标识。 我注意到的一件事是,如果我从同一个上下文对象中添加/保存父和子,那么它可以正常工作。
需要尽快解决这个问题。任何帮助将不胜感激。
答案 0 :(得分:18)
是的,您必须对该操作使用相同的上下文。这就是重点。如果不使用相同的上下文,则必须手动控制将插入哪个对象,哪些对象已更新,哪些对象不会被修改。在您的方案中,序列可以是:
context.Parents.Attach(parent); // just attach as unchanged
context.Childs.Add(child); // add as inserted
parent.Childs.Add(child); // make connection between existing and inserted object
context.SaveChanges();
另一种方法可以是:
child.Parent = parent;
context.Childs.Add(child); // both child and parent are marked as inserted!!!
context.Entry(parent).State = EntityState.Unchanged; // set parent as unchanged
context.SaveChanges();
答案 1 :(得分:0)
此外,如果你有类似的话:
public class B
{
[Key]
public int Id {get;set;}
public AId {get;set;}
//... other properties here
[ForeignKey("AId")]
public virtual A ParentA {get;set;}
}
你只能将外键设置为DB中现有的A id条目,并保留 ParentA null,而context.SaveChanges()
它将按预期工作(不创建另一个A条目) DB)。
答案 2 :(得分:0)
以下代码适用于这种情况。
networkDbo.Form.Id = forms.Id; // <-- AGAIN assigning FK // Form is Parent Table
this.dbContext.Form.Attach(formsdbo); // Attach the parent value to db Context
this.dbContext.Network.Attach(networkDbo); // network is Child
this.dbContext.Entry(networkDbo).State = EntityState.Added; // Entity State is Added.
this.dbContext.SaveChanges(); // Save the Db context.