实体框架DbContext正在尝试插入已存在的数据

问题描述 投票:0回答:1

我有两个DbContext课程。 ServerContext拥有UserContext的外键。

ServerContext中:

public ServerContext(DbContextOptions<ServerContext> options)
  : base(options) {
}

public DbSet<Server> Server { get; set; }

protected override void OnModelCreating(ModelBuilder builder) 
{
    base.OnModelCreating(builder);
    builder.Entity<Server>().ToTable("Server");

    builder.Entity<User.User>().HasMany(x => x.Servers).WithOne(x => x.User);
}

服务器:

public class Server 
{
    public string ServerId { get; set; }

    [Required]
    [InverseProperty("User")]
    public string UserId { get; set; }
    public virtual User.User User { get; set; }
}

的UserContext:

public class UserContext : IdentityDbContext<User> 
{
    public UserContext(DbContextOptions<UserContext> options)
      : base(options) 
    {
    }

    public DbSet<User> User { get; set; }

    protected override void OnModelCreating(ModelBuilder builder) 
    {
        base.OnModelCreating(builder);
        builder.Entity<User>().ToTable("User");
    }
}

用户:

public class User : IdentityUser 
{
    public virtual ICollection<Server.Server> Servers { get; set; }
}

在启动时,我将所有Server数据提取到缓存中并每分钟更新一次。

错误发生在模型中。在模型我正在使用服务器数据。之后,我正在检查服务器数据是否包含非空用户数据。它是null,我从数据库加载它(在此步骤中抛出错误)。

public async Task OnGetAsync() 
{
    Servers = await this.ServerManager.GetServersAsync();

    foreach (var server in Servers) 
    {
        if(server == null) 
            continue;

        // This code triggers the error
        var user = await UserManager.FindByIdAsync(server.UserId);

        if(user == null) 
           continue;

        server.User = user;
    }
}

用户:

  public class User : IdentityUser {

    public virtual ICollection<IdentityRole> Roles { get; set; }

    public virtual ICollection<Server.Server> Servers { get; set; }
  }

6个查询一个用户数据:https://pastebin.com/ud9eeKKe

每分钟后我都保存数据,我收到以下错误:

DbUpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常MySql.Data.MySqlClient.MySqlException:重复条目'2f2469d5-b35e-42d8-a90c-a6cc3b899b5a'用于键'PRIMARY'MySql.Data.MySqlClient.MySqlException:重复条目'2f2469d5-b35e-42d8-a90c-a6cc3b899b5a'for key'主'。

asp.net asp.net-core .net-core entity-framework-core
1个回答
1
投票

正如您所提到的,您可以更改GetServersAsync方法的代码,我希望DbContext-Call看起来类似于:

return ServerContext.Servers;

您可以将其更改为:

return ServerContext.Servers.Include(u=>u.User);

这样,您可以跳过导致外部错误的错误,因为用户已经填充了。

实际发生错误,因为您将User-Property设置为跟踪的实体。

或者,您可以在保存之前将User-Property设置为null。或者,在将User设置为User-Property之前,您可以将User设置为EntityEntry(对于Performance-issues,我不建议这样做)。

作为另一种选择,您可以集成Lazy-Loading,它与EF Core 2.1一起引入,如here所述。

更新:

您可以加载服​​务器NotTracked以防止保存问题:

return ServerContext.Servers.AsNoTracking();

然后你可以添加用户,就像你已经做的那样......之后,在保存服务器之前,你必须执行以下步骤:

  1. 再次将User设置为null
  2. 将服务器对象添加为已更新到上下文
  3. 致电SaveChanges
© www.soinside.com 2019 - 2024. All rights reserved.