我有以下情况:
我的EF6数据库中有一个Parent
实体第一个数据模型
public partial class Parents
{
public Parents()
{
this.Childs = new HashSet<Childs>();
}
public int IdParent { get; set; }
public string Description { get; set; }
public virtual ICollection<Childs> Childs { get; set; }
}
和Child
实体
public partial class Childs
{
public int IdChild { get; set; }
public int IdParent { get; set; }
public string Description { get; set; }
public virtual Parents Parents { get; set; }
}
然后我填充对象:
Parents parent = new Parents();
parent.Description = "Test parent";
List<Childs> childList = new List<Childs>();
childList.Add(new Childs { Description = "Test child 1" });
childList.Add(new Childs { Description = "Test child 2" });
现在我做这个操作:
using (CUSTOMER_Entities context = new CUSTOMER_Entities())
{
//adding parent and childs to the context (WITHOUT ANY LINK OR FOREING KEY SET)
context.Parents.Add(parent);
context.Childs.AddRange(childList);
context.SaveChanges();
}
我的问题是:为什么在SaveChanges之后我将孩子们保存在数据库中并使用正确的&#34; IdParent&#34;?
通常我会这样做:using (CUSTOMER_Entities context = new CUSTOMER_Entities())
{
context.Parents.Add(parent);
foreach (var child in childList)
{
parent.Childs.Add(child);
}
context.SaveChanges();
}
或
using (CUSTOMER_Entities context = new CUSTOMER_Entities())
{
context.Parents.Add(parent);
foreach (var child in childList)
{
child.IdParent = parent.IdParent;
context.Childs.Add(child);
}
}
什么是正确的方法?
答案 0 :(得分:1)
(我将为实体和参考使用单数名称)
EF连接父母和孩子的原因是Parent
的{{1}} = 0且孩子都有Id
= 0。
在幕后,EF始终执行关系修正。这是一个EF尝试将导航属性(如IdParent
和Child.Parent
)与原始主键和外键值(Parent.Children
,Id
)同步的过程。将子项添加到上下文后,EF连接父项和子项,因为键值(PK和FK)为0。
当EF插入数据时,它首先插入父数据。它会立即从数据库中获取其生成的PK值,并在保存之前将其写入子项的IdParent
属性。
您可以通过手动设置来覆盖此自动关联设置。假设您要插入两个有孩子的父母:
IdParent
这会导致异常,因为不能将孩子分配给两个父母。但如果你这样做......
context.Parents.Add(parent);
context.Parents.Add(parent2);
context.Childs.AddRange(childList);
...您已手动设置关联,EF很高兴。
答案 1 :(得分:0)
有多种方法可以做到这一点,我自己对EF很新,所以我不确定一个人是否有优势。
EF应该为您处理大部分FK关系,即使您可以根据需要手动指定。
EX1:
Parents P = New Parent();
P.Childs.Add(New Childs());
context.Parents.Add(P);
//Now child is part of this particular parent's collection, it should be able
//to determine which foreign key to use automatically when you...
context.SaveChanges();
EX2:
//Code here to pull parent
Parents P = context.Parents.Find(ParentID);
//Assign child to said parent during instantiation
Childs C = new Childs{ Description = "Test", Parents = P};
context.Childs.Add(C);
context.SaveChanges();
EX3:
//Use convention or annotations
//convention naming for foreign key
public partial class Childs
{
public int IdChild { get; set; }
//public int IdParent { get; set; }
public int ParentsID {get; set;}// <---
public string Description { get; set; }
public virtual Parents Parents { get; set; }
}
例如3,另请参阅:https://msdn.microsoft.com/en-us/library/jj679962(v=vs.113).aspx