In this lesson, you will learn how to identify and diagnose why changes made to your domain objects fail to persist in the database due to EF Core’s tracking mechanism.
The Tracking Mismatch
EF Core uses a ChangeTracker to monitor every entity loaded into a DbContext instance. When you call SaveChanges(), EF Core generates SQL commands based on the state of these entities (e.g., Modified, Added, Deleted). If you update an object and find that your database remains unchanged, it is almost always because the entity is currently Detached or the change occurred outside the context’s awareness.
Debugging with Entry Metadata
If an update isn't persisting, the first step is to inspect the entity's current state within the tracker. You can use the Entry method to see exactly what EF Core thinks is happening with your object:
var entry = _context.Entry(myEntity);
Console.WriteLine($"Current State: {entry.State}");
foreach (var property in entry.Properties)
{
Console.WriteLine($"{property.Metadata.Name}: Original={property.OriginalValue}, Current={property.CurrentValue}");
}
Common Debugging Scenarios
- Disconnected Entities: If you load an entity in one request or method, return it to the client, and then attempt to save it later without re-attaching it, EF Core treats it as
Detached. TheChangeTrackeris not watching it, so your modifications are ignored. - No-Tracking Queries: If you used
.AsNoTracking()in your original query, the entities are returned as plain objects. Modifying these objects will never trigger an update because they were never added to the internal tracker. - Property Shadowing: Sometimes, you may be modifying a property, but the
ChangeTrackerhasn't registered the change because the entity wasn't in theTrackedstate when the property was assigned.
When debugging, always check if entry.State is Unchanged despite your code changes. If it is, the entity is likely Detached. You may need to use _context.Update(myEntity) to explicitly tell EF Core to start tracking that object and mark all its properties as modified.
Key Takeaway: If SaveChanges() does nothing, your entity is likely Detached or was retrieved via a NoTracking query; use the ChangeTracker.Entry() metadata to inspect the internal state and verify if EF Core is actually "watching" your object.