Hopefully the following code snippet clear enough to explain the problem. _db
is an instance of DbContext
.
// this scenario is only for learning purpose
Author a = _db.Authors.Find(1831);
int id = a.AuthorId;
a = null;
Author stub = new Author { AuthorId = id };
_db.Remove(stub);
_db.SaveChanges();
The code above produces
'The instance of entity type 'Author' cannot be tracked because another instance with the same key value for {'AuthorId'} 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.'
How to free a
from being tracked?
In Entity Framework, change tracking is enabled by default. You can also disable change tracking by setting the AutoDetectChangesEnabled property of DbContext to false. If this property is set to true then the Entity Framework maintains the state of entities.
No-Tracking query using AsNoTracking() extention method The AsNoTracking() extension method returns a new query and returned entities do not track by the context. It means that EF does not perform any additional task to store the retrieve entities for tracking.
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.
EF Core change tracking works best when the same DbContext instance is used to both query for entities and update them by calling SaveChanges. This is because EF Core automatically tracks the state of queried entities and then detects any changes made to these entities when SaveChanges is called.
There are a variety of ways to do this, but I find this the most simple since you're trying to detach a specific entity.
_db.Entry(a).State = EntityState.Detached
As a plus it doesn't require changing any other code, including however you fetched the entity itself.
This one line makes it very clear of the intent. It also allows the following:
I dislike the idea of changing existing queries on a DbContext
when all I want to do is detach something.
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