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:
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.
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; } }
When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.
AsNoTracking(IQueryable)Returns a new query where the entities returned will not be cached in the DbContext or ObjectContext. This method works by calling the AsNoTracking method of the underlying query object.
An entity is in this state immediately after it has been created and before it is added to the object context. An entity is also in this state after it has been removed from the context by calling the Detach(Object) method or if it is loaded by using a NoTrackingMergeOption.
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.
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.
When you register your service it will be using 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.
This will help you!
AsNoTracking()
By default, EntityFramework tracks changes on entities that are queried and saves changes when you call SaveChanges() on the context.
If it is already tracking product:42, and you add or attach a product with the Id:42 that it hasn't seen, there is ambiguity as to which represents the source of truth.
AsNoTracking produces objects which are not added to the change tracking mechanism, which you should use if you aren't using the change tracking features, because it's faster and makes your intent more explicit.
Most often, this is a scope issue. You don't expect there to be something in the cache, but surprise, there is - usually because of some global variable or a context which was not disposed - Both very common. When you find the offending DbContext, either wrap it in a 'using' or add AsNoTracking.
What difference does .AsNoTracking() make?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With