Как я могу добавить родительский и 2 уровень дочернего объекта с обновлением 1 уровня дочернего в EF Core? - PullRequest
0 голосов
/ 19 мая 2019

У меня есть родительский объект со списком Child1. Объект Child1 имеет список объектов Child2. Моя цель заключается в создании родительских и двухуровневых дочерних (Child2) сущностей в базе данных с обновлением parentId для сущности Child1. Позвольте мне сообщить подробности.

Parent{

int ID;
List<Child1> child1;
.....
}

Child1{
int ID;
int parent_ID;
....
List<Child2> child2;

}

Child2{
int ID;
int child1_ID;

....

}

Как мне выполнить эту операцию с помощью EF Core?

1 Ответ

0 голосов
/ 20 мая 2019

Вам, вероятно, понадобится уточнить, что вы собираетесь сделать:

Например, на основе вашего описания, если у вас есть текущий:

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) или вы работаете с набором ссылок, которые могут быть продублированы, или вложеннымиструктура ссылок.Если вы прикрепите объект, который уже связан с контекстом, вы получите исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...