【问题标题】:How can I add multiple navigation properties with the same Foreign Key in EF.Core 5?如何在 EF.Core 5 中添加具有相同外键的多个导航属性?
【发布时间】:2021-04-09 11:32:16
【问题描述】:

我正在尝试在 EF.Core 5 中添加新对象的集合。这些对象包含以导航属性和包含 FK 对象的属性表示的一对多关系。

每当我尝试使用 .AddRange(entities);我收到“无法跟踪实体类型 '{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 Fluent 映射

 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);         

        }
    }

现在我收到错误消息“附加现有实体时,请确保仅附加一个具有给定键值的实体实例。”

【问题讨论】:

    标签: c# .net entity-framework entity-framework-core one-to-many


    【解决方案1】:

    我想知道您最初是如何创建实体的?如果你有类似的东西

    MyEntity myEntity = new () {
        Id = 637535121932347380,
        Holder = new() {
            Id = 10,
            Name = "Unit Test 0"
        }
    }
    

    那么您不需要显式分配HolderId - 实体框架会自行计算。因为你正在分配,它可能认为有另一个Holder对象具有相同的键

    更新:如果第一个分配工作正常,而第二个抛出异常 - 更加好奇你是如何完成分配的?我假设你 ICollection&lt;MyEntity&gt; 在关系的 one 方面。如果您改为将 MyEntityes 分配给集合会怎样?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 1970-01-01
      相关资源
      最近更新 更多