EF Core добавляет родителя и потомка в одну транзакцию - PullRequest
1 голос
/ 13 февраля 2020

У меня есть стандартная конструкция «родители / дети»:

class Parent {
    Guid Id;
    List<Child> Children;

    public Parent() {
        Id = Guid.NewGuid();
        this.Children = new List<Child>();
    }

    public AddChild(Child ch) {
        this.Children.Add(ch);
    }
}

class Child {
    Guid Id;

    public Child() {
        Id = Guid.NewGuid();
    }
}

Мое отображение выглядит так:

public void Configure(EntityTypeBuilder<Parent> builder)
{
    builder.ToTable("Parents");
    builder.HasKey(x => x.Id);

    builder.HasMany(p => p.Children)
        .WithOne()
        .HasForeignKey("ParentId");
}

public void Configure(EntityTypeBuilder<Child> builder)
{
    builder.ToTable("Children");
    builder.HasKey(x => x.Id);
}

Теперь, в моем методе обслуживания (добавьте дочерний элемент к родительскому, создайте родительский в случай отсутствия в системе):

var parent = await _parentsRepository.GetParent(parentId);

if (parent == null)
{
    parent = new Parent();
    await _parentsRepository.AddAsync(customerMembersip); // adding parent to context, with empty Children collection, but not saving to DB yet
}

parent.AddChild(new Child()); // this make this new Child in Parent object to be in state "Modified", but in fact should be in state "Added". Why?

// save changes here

Другими словами, почему при добавлении дочернего элемента к родительскому элементу (родительский элемент только что добавлен в контекст) дочерний элемент рассматривается как Изменено ? Но если я получаю родителя из репо, и он сразу же попадает в контекст, а затем я добавляю ребенка, то ребенок рассматривается как Добавлено .

Редактировать:

Это может быть связано с тем, что Id (типа Guid) генерируется в коде C#, поэтому EF «думает», что это существующая сущность, поэтому он помечает как «Модифицированный». Но я не совсем понимаю, почему, если Parent уже существует в БД (_parentsRepository возвращает фактическую сущность)

1 Ответ

0 голосов
/ 09 марта 2020

Отвечая на мой собственный вопрос.

В Asp. net core 3.0 (то есть в EF Core 3.0) вам необходимо изменить отображение Child с:

public void Configure(EntityTypeBuilder<Child> builder)
{
    builder.ToTable("Children");
    builder.HasKey(x => x.Id);
}

на:

public void Configure(EntityTypeBuilder<Child> builder)
{
    builder.ToTable("Children");
    builder.Property(x => x.Id).ValueGeneratedNever(); // change is here!
}

Надеюсь, это поможет другим.

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