【问题标题】:EF Core duplicate keys: The instance of entity type '' cannot be tracked because another instance with the key value '' is already being trackedEF Core 重复键:无法跟踪实体类型“”的实例,因为已在跟踪具有键值“”的另一个实例
【发布时间】:2021-06-11 19:56:27
【问题描述】:

我正在使用 Blazor Server 中的 EF Core 处理表单。我在实体跟踪方面遇到了许多问题,因此我将所有查询都设置为 AsNoTracking,并设计了我的服务来为每个查询创建一个新的 dbcontext 实例。我认为这是合适的,因为不会编辑任何返回值 - 只会存储用户输入的表单数据和对查询字段的 id 引用,例如员工编号。对于插入数据,我使用this:

using var context = Factory.CreateDbContext();
context.SetupForm.Attach(model);
context.Entry(model).State = EntityState.Added;
await context.SaveChangesAsync();

我附加数据而不是添加数据,然后将表单对象状态设置为已添加。这可确保 EF Core 在插入表单数据时不会尝试插入现有员工对象。

问题始于表单的一部分,该部分可以包含用户想要的任意数量的项目。选择几个员工并输入相关数据。当他们提交表单时,他们可能在多个项目中选择了同一个员工。由于这些员工是从不同的上下文中选择的,因此它们是具有相同 ID 的两个独立实例。当然,EF Core 不喜欢这样,会抛出这样的错误:

The instance of entity type 'Principal' cannot be tracked because another instance with the key value '{EmployeeID: 1234}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

我了解为什么会发生此错误,但我需要能够以这种方式附加多个实体。我该如何解决这个问题?

我可以做的一件事是手动分配外键,但这会很严格,并且需要在模型更改时进行更新。

【问题讨论】:

    标签: c# entity-framework-core blazor change-tracking


    【解决方案1】:

    试试这个

    using var context = Factory.CreateDbContext();
    
    context.Set<Principal>().Add(model);
    //or maybe context.Principals.Add(model);
    
    await context.SaveChangesAsync();
    

    【讨论】:

    • 这究竟是为了什么? Set 与为该类型使用上下文的 DbSet 不一样吗?
    • 我看不到您的 dbcontext。我想你可以试试 context.Principals.Add(model);
    • 主体是主模型的属性,因此我无法将我的模型添加到 dbcontext。如果不清楚,我可以澄清这个问题。
    【解决方案2】:

    这似乎可以解决问题!它所做的是将缺少密钥的任何实体标记为已添加。否则,该实体将被完全忽略。

    using var context = Factory.CreateDbContext();
    context.ChangeTracker.TrackGraph(model, node =>
    {
         if (!node.Entry.IsKeySet)
         {
              node.Entry.State = EntityState.Added;
         }
    });
    await context.SaveChangesAsync();
    

    不需要插入任何具有密钥的项目。将它们视为未跟踪然后解决任何重复问题并仅插入需要它的行。

    更多信息:https://docs.microsoft.com/en-us/ef/core/change-tracking/identity-resolution#resolve-duplicates

    【讨论】:

      猜你喜欢
      • 2023-01-03
      • 1970-01-01
      • 2022-01-02
      • 2020-01-31
      • 1970-01-01
      • 1970-01-01
      • 2020-09-19
      • 2019-12-29
      • 1970-01-01
      相关资源
      最近更新 更多