【问题标题】:Seeding Error: "The instance of entity type cannot be tracked because another instance with the same key value for is already being tracked"播种错误:“无法跟踪实体类型的实例,因为已跟踪具有相同键值的另一个实例”
【发布时间】:2021-11-29 21:40:54
【问题描述】:

我在播种数据时遇到错误。

型号:

public class Federation
{        
    public string FName { get; set; }        
}

配置:

public class FederationConfiguration : IEntityTypeConfiguration<Federation>
{        
    public void Configure(EntityTypeBuilder<Federation> builder)
    {
        builder.HasKey(t => t.FName);
        builder.Property(t => t.FName)
            .HasMaxLength(20)
            .IsRequired();
    }
}

在 DbContext 中

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());            
    base.OnModelCreating(builder);
}

在播种方法中,我只是尝试将样本数据添加到数据库中:

public static class SeedFederations
{        
    public static async Task SeedFederationsDataAsync(ApplicationDbContext context)
    {
        if (context.Federations.Any())
        {
            return;   // DB has been seeded
        }
        context.Federations.AddRange(
            new Federation { FName = "FIFA" },
            new Federation { FName = "UEFA" },
            new Federation { FName = "UEFA" },
            new Federation { FName = "AFC" }
         );
        context.SaveChanges();
        await context.SaveChangesAsync();
    }
}

我已尝试将另一组数据植入数据库:

public static async Task SeedAppLicationData(ApplicationDbContext context)
{
    await SeedCountries.SeedCountriesDataAsync(context);
    await SeedTeamTypes.SeedTeamTypesDataAsync(context);
    await SeedTeams.SeedTeamsDataAsync(context);
    await SeedBettingTypes.SeedBettingTypesDataAsync(context);
    await SeedFederations.SeedFederationsDataAsync(context); // only error here
}

其他播种没问题,只有最后一个有问题。它不会播种数据,当我设置调试时,我会收到以下消息:

无法跟踪实体类型“Federation”的实例,因为已经在跟踪另一个与 {'FName'} 键值相同的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。 C...

我已经尝试过:修改字段名称以确保与其他表不一样。

请帮帮我。

谢谢

【问题讨论】:

  • 只是为了检查一下,您使用不同的值吗?您在种子数据中输入了两次“UEFA”,也许重复的键会产生问题?

标签: c# entity-framework web asp.net-core-mvc seed


【解决方案1】:

您的数据库上下文被多个请求共享,这意味着您正在编辑的实体已经被跟踪。

这可能是因为您的存储库服务是 Singleton 而不是 Scoped,因此您的 DB 上下文在被拉出时被跟踪的实体被重用,然后放回 DB 上下文的同一实例中。

您应该做的是拥有一个 Scoped Repository,这意味着将为每个请求创建一个新实例。同样,您还将拥有每个请求的数据库上下文。

当您注册服务时,它将使用 services.AddSingleton<..>

将此更改为 services.AddScoped<..>,当您将其注入控制器时,您将获得每个请求的新实例,并且您的更新应该可以正常工作。

或者尝试后仍有问题,可以尝试以下方法,仅供参考:

  public static async Task SeedFederationsDataAsync(ApplicationDbContext context)
    {
        try
        {   
          if (context.Federations.Any())
            {
                return;   // DB has been seeded
            }
            context.Federations.AddRange(
                new Federation { FName = "FIFA" },
                new Federation { FName = "UEFA" },
                new Federation { FName = "UEFA" },
                new Federation { FName = "AFC" }
             );
            context.SaveChanges();
            await context.SaveChangesAsync();
        }
        catch (Exception e)
        {
             // handle correct exception
             // log error
             return false;
        }
    }

【讨论】:

    猜你喜欢
    • 2022-01-02
    • 2023-01-03
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    相关资源
    最近更新 更多