EF Core 在同一个事务中添加 Parent 和 Child

EF Core adding Parent and Child in same transaction

我有标准的parent/children设计:

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

换句话说,为什么将子项添加到父项(父项刚刚添加到上下文)会使子项被视为 已修改?但是,如果我从回购中获取父项并且它立即在上下文中,然后我添加子项,那么子项将被视为 Added.

编辑:

可能是因为Id(Guid类型)是在C#代码中生成的,因此EF "thinks"是存在的实体,因此标记为"Modified"。但是我不太明白为什么,如果 Parent 已经存在于数据库中(_parentsRepository returns 实际实体)

回答我自己的问题。

在 Asp.net 核心 3.0(因此 EF 核心 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!
}

希望对其他人有所帮助。