C# 如何在EF.Core 5中使用相同的外键添加多个导航属性?

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

我试图在EF.core5中添加一组新对象。这些对象包含导航属性中表示的一对多关系以及包含FK对象的属性

每当我尝试和.AddRange(实体)时;我得到“无法跟踪实体类型{object}的实例,因为已经在跟踪另一个具有{Id}相同键值的实例。”

如何让ef.core理解导航属性是相同的,并且只插入一次

另外,我还不担心数据库中的实际内容,当我调用.AddRange(entities)时,这会失败;这是在构建上下文之后的第一次

我把它分解成了一个foreach循环,当抛出异常时,可以看到它是
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分配给集合会怎么样