System.InvalidOperationException: The instance of entity type 'EntityName' cannot be tracked because another instance with the same key value is already being tracked.
ID: dotnet/ef-no-tracking-query
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 8 | active | — | — | — |
Root Cause
This InvalidOperationException occurs when EF Core's change tracker already contains an entity with the same primary key. Common when attaching or updating entities loaded from a different DbContext instance or deserialized from a request. Fix by using AsNoTracking for read-only queries or properly managing DbContext scope.
genericWorkarounds
-
90% success Use AsNoTracking() for read-only queries that do not need change tracking
Add .AsNoTracking() to queries that only read data: var items = await dbContext.Products.AsNoTracking().ToListAsync(). For a global default, configure in DbContext: optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking). Then explicitly use .AsTracking() only when updates are needed
-
85% success Detach the existing tracked entity before attaching the new instance
Find and detach the tracked entity: var local = dbContext.Set<Entity>().Local.FirstOrDefault(e => e.Id == entity.Id); if (local != null) dbContext.Entry(local).State = EntityState.Detached; Then attach the new entity: dbContext.Update(entity);
Dead Ends
Common approaches that don't work:
-
Creating a new DbContext instance for every operation to avoid tracking conflicts
70% fail
Defeats the purpose of the Unit of Work pattern; transactions cannot span operations, causing data consistency issues. Also causes performance problems from repeated context creation overhead
-
Calling DbContext.ChangeTracker.Clear() before every update operation
75% fail
Discards all tracked changes including pending updates from the same request scope; can cause silent data loss and breaks the expected behavior of other code sharing the same DbContext