[英]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.Add
和Context.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
指向与传递给UpdateComponentOwnerAsync
的componentOwner
相同的引用。 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:几点建议:
context.SaveChangesAsync
.context.SaveChangesAsync
的返回值。 You should get back 1
ie one record updated/created.1
,即更新/创建一条记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.