繁体   English   中英

无法跟踪实体类型“AppUser”的实例,因为已跟踪另一个具有与 {'Id'} 相同键值的实例

[英]The instance of entity type 'AppUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

希望有人可以帮助一个相当新手的 EF/asp.net 核心开发人员……

我的方法之一在 'context.Add(item)' 上失败

该模型:

public class Component : Item
{
    public int Id { get; set; }
    public string ComponentName { get; set; }
    public string ComponentDescription { get; set; }
}

失败的方法('_user' 是在构造函数中设置的 AppUser):

public async Task<bool> UpdateComponentOwnerAsync(ComponentOwner componentOwner)
{
    var co = new ComponentOwner();
    bool success = false;
    try
    {
        if (componentOwner.Id == 0)
        {
            co.Component = componentOwner.Component;
            co.User = componentOwner.User;
            co.ModifiedDate = DateTime.Now;
            co.UpdatedBy = "Someone";
        }
        else
        {
            co = componentOwner;
        }

        var coNew = (ComponentOwner)await SaveItem(co);
private async Task<Item> SaveItem(Item item)
{
    using var context = _dbContextFactory.CreateDbContext();
    try
    {
        context.Users.Attach(_user);

        if (item.Id == 0)
        {
            context.Add(item);
            await context.SaveChangesAsync();

        }

错误:

System.InvalidOperationException: '无法跟踪实体类型 'AppUser' 的实例,因为已跟踪另一个具有与 {'Id'} 相同键值的实例。 附加现有实体时,确保只附加一个具有给定键值的实体实例。

删除 'context.Users.Attach(_user)' 会导致以下 SQL 异常,所以这似乎需要保留:

SqlException:违反 PRIMARY KEY 约束“PK_AspNetUsers”。 无法在对象“dbo.AspNetUsers”中插入重复键。 重复键值为 (7344f007-4463-46ab-b435-651fb9e0e29a)。 当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Components”中为标识列插入显式值。 该语句已终止。

我看过类似的帖子,他们都认为这是由于范围不正确或“AppUser 被跟踪”所致。 据我所知,范围不是必需的(在我的 program.cs 文件中,我有以下内容:

builder.Services.AddDbContextFactory<DBContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddDbContext<DBContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));`

而且我不明白为什么 AppUser 会在其他地方被跟踪。

希望有人能告诉我哪里出错了!

您尝试添加一条已存在的记录。 Context.AddContext.Update完全按照他们所说的去做。

如果您不完全理解值类型和引用类型之间的区别,我建议您开始阅读。

UpdateComponentOwnerAsync中,如果componentOwner是现有记录,则componentOwner.Id不是0

所以

co = componentOwner;

componentOwner引用分配给co

然后你调用SaveItem(co)试图做一个

context.Add(item [actually co])

失败了。 co指向与传递给UpdateComponentOwnerAsynccomponentOwner相同的引用。 当您首先从数据库中获取componentOwner时,您就有了一个重复的 id。

您没有说明如何获得componentOwner以及将其 Id 设置为0的逻辑,因此我无法提出有意义的解决方案。

几点建议:

  1. 您应该在代码和数据管道中区分更新和创建/添加。 它使逻辑更直接,更容易理解。
  2. 检查context.SaveChangesAsync的返回值。 您应该返回1 ,即更新/创建一条记录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM