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!
}
希望对其他人有所帮助。
我有标准的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!
}
希望对其他人有所帮助。