Вам, вероятно, понадобится уточнить, что вы собираетесь сделать:
Например, на основе вашего описания, если у вас есть текущий:
Parent: "Dad"
Child1s (1)
-> Child1: "Peter"
Child2s (0)
, и вы хотите добавитьnew Parent "Mom", переместите "Peter" из "Dad" в "Mom" и добавьте новый "Jill" для Child 2 в "Peter"
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
) или вы работаете с набором ссылок, которые могут быть продублированы, или вложеннымиструктура ссылок.Если вы прикрепите объект, который уже связан с контекстом, вы получите исключение.