简体   繁体   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

Hopefully someone can help a fairly novice EF/ asp.net core dev...希望有人可以帮助一个相当新手的 EF/asp.net 核心开发人员……

One of my methods is failing on 'context.Add(item)'我的方法之一在 'context.Add(item)' 上失败

The Model:该模型:

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

The method that fails ('_user' is AppUser which is set in the constructor):失败的方法('_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();

        }

The error:错误:

System.InvalidOperationException: 'The instance of entity type 'AppUser' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. System.InvalidOperationException: '无法跟踪实体类型 'AppUser' 的实例,因为已跟踪另一个具有与 {'Id'} 相同键值的实例。 When attaching existing entities, ensure that only one entity instance with a given key value is attached.附加现有实体时,确保只附加一个具有给定键值的实体实例。

Removing 'context.Users.Attach(_user)' results in the following SQL Exception, SO this does need to stay in it seems:删除 'context.Users.Attach(_user)' 会导致以下 SQL 异常,所以这似乎需要保留:

SqlException: Violation of PRIMARY KEY constraint 'PK_AspNetUsers'. SqlException:违反 PRIMARY KEY 约束“PK_AspNetUsers”。 Cannot insert duplicate key in object 'dbo.AspNetUsers'.无法在对象“dbo.AspNetUsers”中插入重复键。 The duplicate key value is (7344f007-4463-46ab-b435-651fb9e0e29a).重复键值为 (7344f007-4463-46ab-b435-651fb9e0e29a)。 Cannot insert explicit value for identity column in table 'Components' when IDENTITY_INSERT is set to OFF.当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Components”中为标识列插入显式值。 The statement has been terminated.该语句已终止。

I've looked at similar posts and they all suggest that it's due to the scope being incorrect or 'AppUser being tracked.我看过类似的帖子,他们都认为这是由于范围不正确或“AppUser 被跟踪”所致。 A scope isn't required as far as I can tell however (in my program.cs file, I have the following:据我所知,范围不是必需的(在我的 program.cs 文件中,我有以下内容:

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

and I can't see why AppUser would be being tracked elsewhere.而且我不明白为什么 AppUser 会在其他地方被跟踪。

Hopefully someone can tell me where I'm going wrong!希望有人能告诉我哪里出错了!

Your trying to add a record that already exists.您尝试添加一条已存在的记录。 Context.Add and Context.Update do exactly what they say. Context.AddContext.Update完全按照他们所说的去做。

If you don't fully understand the differences between value and reference types I suggest you start reading.如果您不完全理解值类型和引用类型之间的区别,我建议您开始阅读。

In UpdateComponentOwnerAsync if componentOwner is an existing record then componentOwner.Id is not 0 .UpdateComponentOwnerAsync中,如果componentOwner是现有记录,则componentOwner.Id不是0

Therefore所以

co = componentOwner;

assigns the componentOwner reference to co .componentOwner引用分配给co

You then call SaveItem(co) which attempts to do a然后你调用SaveItem(co)试图做一个

context.Add(item [actually co])

And fails.失败了。 co points to the same reference as componentOwner passed in to UpdateComponentOwnerAsync . co指向与传递给UpdateComponentOwnerAsynccomponentOwner相同的引用。 As you obtained componentOwner from the database in the first place, then you have a duplicate id.当您首先从数据库中获取componentOwner时,您就有了一个重复的 id。

You don't show how you obtained componentOwner and what logic sets it's Id to 0 , so I'm not in a position to suggest a meaningful solution.您没有说明如何获得componentOwner以及将其 Id 设置为0的逻辑,因此我无法提出有意义的解决方案。

A couple of pointers:几点建议:

  1. You should differentiate in your code and data pipeline between Updates and Creates/Adds.您应该在代码和数据管道中区分更新和创建/添加。 It makes the logic more straightforward and easier to understand.它使逻辑更直接,更容易理解。
  2. Check the return value of context.SaveChangesAsync .检查context.SaveChangesAsync的返回值。 You should get back 1 ie one record updated/created.您应该返回1 ,即更新/创建一条记录。

暂无
暂无

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

相关问题 无法跟踪实体类型“ Article”的实例,因为已经跟踪了另一个具有相同键值的{&#39;Id&#39;}实例 - The instance of entity type 'Article' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked 无法跟踪实体类型“用户”的实例,因为已经在跟踪另一个具有相同键值的“Id”实例 - The instance of entity type 'User' cannot be tracked because another instance with the same key value for 'Id' is already being tracked 实体类型的实例 <T> 无法跟踪,因为已经跟踪了另一个具有相同的{&#39;Id&#39;}键值的实例 - The instance of entity type <T> cannot be tracked because another instance with the same key value for {'Id'} is already being tracked 无法跟踪实体类型 Model 的实例,因为已跟踪另一个具有相同 {&#39;Id&#39;} 键值的实例 - The instance of entity type Model cannot be tracked because another instance with the same key value for {'Id'} is already being tracked 无法跟踪实体类型“Bus”的实例,因为已经在跟踪具有相同键值 {'Id'} 的另一个实例 - The instance of entity type ‘Bus’ cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked 无法跟踪实体类型“Item”的实例,因为已跟踪另一个具有与 {'Id'} 相同键值的实例 - The instance of entity type 'Item' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked 无法跟踪实体类型“书签”的实例,因为已经在跟踪具有相同键值 {'ID'} 的另一个实例 - The instance of entity type 'Bookmark' cannot be tracked because another instance with the same key value for {'ID'} is already being tracked 无法跟踪实体类型“ Customer”的实例,因为已经跟踪了另一个键值为“ {Id:…}”的实例 - The instance of entity type 'Customer' cannot be tracked because another instance with the key value '{Id: …}' is already being tracked 无法跟踪实体类型“x”的实例,因为已在跟踪另一个具有键值“{Id: 6}”的实例 - The instance of entity type 'x' cannot be tracked because another instance with the key value '{Id: 6}' is already being tracked 无法跟踪实体类型 X 的实例,因为已跟踪具有键值“{Id:}”的另一个实例 - The instance of entity type X cannot be tracked because another instance with the key value '{Id:}' is already being tracked
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM