C# 如何在EF.Core 5中使用相同的外键添加多个导航属性?
我试图在EF.core5中添加一组新对象。这些对象包含导航属性中表示的一对多关系以及包含FK对象的属性 每当我尝试和.AddRange(实体)时;我得到“无法跟踪实体类型{object}的实例,因为已经在跟踪另一个具有{Id}相同键值的实例。” 如何让ef.core理解导航属性是相同的,并且只插入一次 另外,我还不担心数据库中的实际内容,当我调用.AddRange(entities)时,这会失败;这是在构建上下文之后的第一次 我把它分解成了一个foreach循环,当抛出异常时,可以看到它是C# 如何在EF.Core 5中使用相同的外键添加多个导航属性?,c#,.net,entity-framework,entity-framework-core,one-to-many,C#,.net,Entity Framework,Entity Framework Core,One To Many,我试图在EF.core5中添加一组新对象。这些对象包含导航属性中表示的一对多关系以及包含FK对象的属性 每当我尝试和.AddRange(实体)时;我得到“无法跟踪实体类型{object}的实例,因为已经在跟踪另一个具有{Id}相同键值的实例。” 如何让ef.core理解导航属性是相同的,并且只插入一次 另外,我还不担心数据库中的实际内容,当我调用.AddRange(entities)时,这会失败;这是在构建上下文之后的第一次 我把它分解成了一个foreach循环,当抛出异常时,可以看到它是Hol
Holder
对象的第二个实例,这告诉我EF.Core不知道如何处理“相同”对象的第二个实例
json
[
{
"Id":637535121932347380,
"HolderId":100,
"Holder":{
"Id":100,
"Name":"Unit Test 0",
"Nickname":"Nickname 0"
}
},
{
"Id":637535121932363243,
"HolderId":100,
"Holder":{
"Id":100,
"Name":"Unit Test 0",
"Nickname":"Nickname 0"
}
},
{
"Id":637535121932363330,
"HolderId":100,
"Holder":{
"Id":100,
"Name":"Unit Test 0",
"Nickname":"Nickname 0"
}
}
]
业务逻辑
_context.Properties.AddRange(entities);
await _context.SaveChangesAsync(cancellationToken);
EF.Core流畅映射
internal sealed class HolderMap : IEntityTypeConfiguration<Holder>
{
public void Configure(EntityTypeBuilder<Holder> builder)
{
builder.HasKey(p => p.Id);
builder.Property(p => p.Id).ValueGeneratedNever().IsRequired();
builder.Property(p => p.Name).IsRequired().HasMaxLength(80);
builder.Property(p => p.Nickname).HasMaxLength(96);
builder.HasMany(p => p.Properties).WithOne(p => p.Holder).HasForeignKey(h => h.HolderId);
}
}
internal sealed class PropertyMap : IEntityTypeConfiguration<Property>
{
public void Configure(EntityTypeBuilder<Property> builder)
{
builder.HasKey(p => p.Id);
builder.Property(p => p.Id).ValueGeneratedNever().IsRequired();
//relationships
builder.HasOne(p => p.Holder).WithMany(h => h.Properties).HasForeignKey(k => k.HolderId);
}
}
内部密封类持有者映射:IEntityTypeConfiguration
{
公共void配置(EntityTypeBuilder)
{
HasKey(p=>p.Id);
属性(p=>p.Id).ValueGeneratedNever().IsRequired();
属性(p=>p.Name).IsRequired().HasMaxLength(80);
builder.Property(p=>p.昵称).HasMaxLength(96);
builder.HasMany(p=>p.Properties).WithOne(p=>p.Holder).HasForeignKey(h=>h.HolderId);
}
}
内部密封类属性映射:IEntityTypeConfiguration
{
公共void配置(EntityTypeBuilder)
{
HasKey(p=>p.Id);
属性(p=>p.Id).ValueGeneratedNever().IsRequired();
//关系
HasOne(p=>p.Holder).WithMany(h=>h.Properties).HasForeignKey(k=>k.HolderId);
}
}
现在我收到一条错误消息“在附加现有实体时,请确保仅附加一个具有给定键值的实体实例。”我想知道您首先是如何从中创建实体的?如果你有
MyEntity myEntity = new () {
Id = 637535121932347380,
Holder = new() {
Id = 10,
Name = "Unit Test 0"
}
}
然后,您不需要显式地分配HolderId
——实体框架将自行计算它。因为正在分配,它可能会认为有另一个持有者
对象具有相同的键
更新:如果第一个作业运行正常,而第二个作业抛出异常-更奇怪的是,您是如何完成作业的?我假设您ICollection
位于关系的一侧。如果您将MyEntity
es分配给集合会怎么样