.net 无法跟踪实体类型的实例,因为跟踪了具有相同键值的另一个实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48202403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
instance of entity type cannot be tracked because another instance with same key value is tracked
提问by Ali Raza
I'm using generic repository pattern in asp.net core 2.0 which can not dispose repository object, when I am going to update the entry its updated for one time successfully but when I am trying to update for more then once it throws the following exception:
我在 asp.net core 2.0 中使用通用存储库模式,它无法处理存储库对象,当我要更新条目时,它已成功更新一次,但是当我尝试更新一次时,它抛出以下异常:
The instance of entity type 'Company' cannot be tracked because another instance with the same key value for {'ID'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
无法跟踪实体类型“公司”的实例,因为已跟踪具有相同 {'ID'} 键值的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用 'DbContextOptionsBuilder.EnableSensitiveDataLogging' 来查看冲突的键值。
public ActionResult Edit(Int64 id, Company collection)
{
try
{
// TODO: Add update logic here
interfaceobj.updateModel(collection);
interfaceobj.Save();
return RedirectToAction(nameof(Index));
}
catch(Exception ex)
{
throw ex;
}
}
回答by Rudi Visser
Your DB Context is being shared by multiple requests, meaning that the entity you're editing has been tracked already.
您的数据库上下文被多个请求共享,这意味着您正在编辑的实体已经被跟踪。
This is likely because your repository service is a Singleton rather than Scoped, and so your DB Context is being reused with the entity being tracked when it's pulled out, and then put back in to the same instance of the DB Context.
这可能是因为您的存储库服务是单例而不是 Scoped,因此您的 DB Context 正在与被拉出时被跟踪的实体一起重用,然后放回 DB Context 的同一实例。
What you should be doing instead is having a Scoped Repository, which means that a new instance will be created for each request. Likewise, you will also have a per-request DB Context.
您应该做的是拥有一个Scoped Repository,这意味着将为每个请求创建一个新实例。同样,您还将拥有每个请求的数据库上下文。
When you register your service it will be using services.AddSingleton<..>
当您注册您的服务时,它将使用 services.AddSingleton<..>
Change this to services.AddScoped<..>, when you inject it into your controller you will then get a new instance per request and your updates should work fine.
将此更改为services.AddScoped<..>,当您将其注入控制器时,您将获得每个请求的新实例,并且您的更新应该可以正常工作。
回答by Ehis Anthony
This will help you!
这会帮助你!
AsNoTracking()
回答by MiCoos
You need Detached Entry.
您需要独立条目。
Entry<CustomerBaseInfo>(data).State = EntityState.Detached;
回答by Prince Owen
Just like Rudi Visser suggested, you can face this issue when using one entity across multiple data contexts. In my case, it was something similar to this:
就像 Rudi Visser建议的那样,当跨多个数据上下文使用一个实体时,您可能会遇到这个问题。就我而言,它类似于以下内容:
User user = await DataContext.Users.SingleOrDefaultAsync(u => u.Id == "SomeId");
// Switch to UserManager *_*
var res = await UserManager.ResetPasswordAsync(user, token, password); // Exception thrown
A simple solution would be to try to stick to one DataContext, because UserManagerseems to do some attaching and detaching (maybe) in the background. For example:
一个简单的解决方案是尝试坚持一个DataContext,因为UserManager似乎在后台进行了一些附加和分离(可能)。例如:
User user = await UserManager.FindByIdAsync("SomeId");
var res = await UserManager.ResetPasswordAsync(user, token, password);
回答by Rafael Botelho
Maybe it can help you:
也许它可以帮助你:
services.AddDbContext<...>(ServiceLifetime.Singleton);

