Иногда структура сущности вставляет несколько «родительских» строк после добавления «потомков» в новый (родительский) элемент - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь выяснить, что может вызвать умножение сущности в случае добавления к нему дочерних элементов (соединение один-ко-многим).

Мой код очень сложный, у классов гораздо больше свойствно главная проблема заключается в следующем.

Вот пример кода:

public class Parent
{
    public int Id { get; set; }
    public List<Child> Children { get; set; }
    public string Name { get; set; }
    public Parent()
    {
        Children = new List<Child>();
    }
}

public class Child
{
    public int Id { get; set; }
    public Parent Parent { get; set; }
    public int ParentId { get; set; }
    public string ParentName { get; set; }
}

Ребенок может жить без родителя, как и родитель .

Так что, когда я хочу соединить две сущности, это должно нормально работать в коде. Невозможно создать новый родительский объект, если он уже есть. Процесс линейный.

Например, я создаю три дочерних сначала без родителя (это 1-е состояние) и сохраняя его в Db . Затем я «обрабатываю» сущности (возможно, через день после создания дочерних элементов):

  • Выбор первого дочернего элемента и создание родительского элемента, если не удалось найти один по его имени (дети уже есть в базе данных).

  • Добавление child в список детей родителей.

  • Сохранение dbContext.

  • Цикл, пока у меня есть ребенок, у которого нет родителей.

Пример кода:

public void ProcessChildren()
{
    IDbContextTransaction trans = dbContext.BeginTransaction();
    foreach(var item in Children) //Children is a list of child entities (existing in the DB)
    {
        var parent = dbContext.Parents.SingleOrDefault(x => x.Name == item.ParentName);
        if(parent == null)
        {
            parent = new Parent{Name = item.ParentName};
            dbContext.Parents.Add(parent);
        }
        parent.Children.Add(item);
        dbContext.SaveChanges();
    }
    trans.Commit(); //rollback implemented if it fails
}

То, что у меня есть (только иногда и очень редко), это 3 родителя и 3 ребенка-ведьмы не имеют ParentIds , так что (для меня) похоже, что EF каким-то образом разбился и сделалэто случайно.

Таким образом, эта ошибка происходит во время огромного процесса (из нескольких сотен тысяч детей было создано несколько десятков тысяч родителей), и вероятность появления ошибки все еще очень мала (на самом деле не воспроизводится намеренно). Однако в моей системе это вызывает последствия.

Кто-нибудь слышал о таком поведении? Может быть, проблема в EF (EntityFramework 6.2.0 Nuget) или расширении Npgsql (EntityFramework6.Npgsql 3.1.1 Nuget)?

РЕДАКТИРОВАТЬ: Добавление примера кода для сохранения и созданияюридические лица. Edit2: Исправление исключительной ситуации родительской нулевой ссылки. Извините, код написан здесь, это пример того, как он работает, а не сам код.

1 Ответ

0 голосов
/ 17 октября 2019

После этой строки вы просто добавляете нового Parent в контекст базы данных, но ваша «родительская» переменная не меняется и она останется нулевой.

if(parent == null)
{
    dbContext.Parents.Add(new Parent{Name = item.ParentName});
}

Таким образом, каждый раз, когда parent будет нулевым,Ваш код будет сбой, когда вы захотите получить доступ к пустой переменной здесь parent.Children.Add(item);

Вы можете попытаться назначить родительскую переменную для вновь добавленного родительского объекта.

if (parent == null)
{
    parent = dbContext.Parents.Add(new Parent{Name = item.ParentName});
}
...