我有一个具有Child1列表的父实体。 Child1实体具有Child2实体列表。 我的目标是在datyabase上创建Parent和2级child(Child2)实体,并更新Child1实体上的parentId。让我提供详细信息。
Parent{
int ID;
List<Child1> child1;
.....
}
Child1{
int ID;
int parent_ID;
....
List<Child2> child2;
}
Child2{
int ID;
int child1_ID;
....
}
如何通过EF Core实现此操作?
答案 0 :(得分:0)
您可能需要澄清打算发生的事情:
例如,根据您的描述,如果您拥有当前信息:
Parent: "Dad"
Child1s (1)
-> Child1: "Peter"
Child2s (0)
您要添加一个新的“父母”“妈妈”,将“彼得”从“爸爸”移到“妈妈”,并在“彼得”下添加一个新的孩子2“吉尔”
Parent: "Dad"
Child1s (0)
Parent: "Mom"
Child1s: (1)
-> Child1: "Peter"
Child2s (1)
-> Child2: "Jill"
using(var context = new FamilyDbContext())
{
var parent1 = context.Parents.Single(x => x.Name == "Dad");
var parent2 = new Parent {Name = "Mom"};
var child = parent1.Child1s.Single(x => x.Name == "Peter");
parent1.Children.Remove(child);
parent2.Children.Add(child);
child.Parent = parent2;
var grandChild = new Child2{Name = "Jill", Child = child};
child.Child2s.Add(grandChild);
context.SaveChanges();
}
不要尝试在子级上更新“ ParentID”等,而是在要在父级之间移动实体的情况下更新引用。 EF将管理FK。
编辑:如果Child1存在而没有可选的父级,并且您想要向其添加一个Child2并将其关联到新的父级:
using(var context = new FamilyDbContext())
{
var child = context.Child1s.Single(x => x.Name == "Peter");
var parent = new Parent {Name = "Dad"};
var grandChild = new Child2 { Name = "Jill", Child1 = child };
child.Parent = parent;
parent.Child1s.Add(child);
context.SaveChanges();
}
要注意的是实体和不断变化的关联等,是要确保所有有问题的实体都与同一个DbContext实例关联。通常,您会发现将实体作为参数接受的方法,然后在尝试在新的DbContext下添加实体并关联作为参数传入的实体时遇到问题。这些实体可以是与不同上下文关联的实体,也可以视为导致错误或重复数据的新实体。可以将实体附加到上下文,但是只有当您确定传递的实体可以信任并且尚未与上下文关联时,才需要仔细进行此操作。
因此,以上示例演示了如何在DbContext范围内加载和创建所有受影响的实体。这样的事情可能会引起问题:
public void MoveChild(Child1 child)
{
using (var context = new FamilyContext())
{
var parent = new Parent {Name = "Dad"};
var grandChild = new Child2 { Name = "Jill", Child1 = child };
child.Parent = parent;
parent.Child1s.Add(child);
context.SaveChanges();
}
}
原因是“子级”与我们的上下文无关。它可能与另一个上下文相关联,或者已经被反序列化,从而使其实际上只是一个普通对象而不是被跟踪实体。
要附加它,您可以执行以下操作:
public void MoveChild(Child1 child)
{
using (var context = new FamilyContext())
{
child = context.Child1s.Attach(child);
var parent = new Parent {Name = "Dad"};
var grandChild = new Child2 { Name = "Jill", Child1 = child };
child.Parent = parent;
parent.Child1s.Add(child);
context.SaveChanges();
}
}
但是,例如,如果DbContext是作用域级别的模块级(而不是using
块),或者您正在对可能重复的引用集合或嵌套结构进行操作,则此类代码需要小心参考。如果您附加了已经与上下文关联的实体,则将获得异常。