ChangeTracker, EntityEntry & Entity States in Entity Framework Core

The ChangeTracker in EF Core tracks changes made to every entity by assigning them the Entity States. It uses the EntityEntry class to store the tracking information of a given entity. The Entity States represents the state of an entity. The Entity State can be Added, Deleted, Modified, Unchanged or Detached. For example, when we add a new entity to DbContext using the Add / AddRange method, the DbContext sets the state of the entity as Added. When we query and load the entity the state is set to Unchanged. If we make any changes to the entity then its state becomes Modified The SaveChanges uses these states to determine to generate the SQL query ( Insert,Update or Delete )

Source Code:
The source code of this project available in GitHub. It also contains the script of the database

ChangeTracker

The ChangeTracker class is responsible for keeping track of entities loaded into the Context. It does so by creating an EntityEntry class instance for every entity. The ChnageTracker maintains the Entity State, the Original Values, Current Values, etc of each entity in the EntityEntry class.

EntityEntry 

Each entity tracked by the context gets an instance of the EntityEntry class. It stores the Change tracking information of the given entity and also has methods, which you can use to manipulate the Change Tracking Information.

You can access instance of the EntityEntry of a given entity, using the DbContext.Entrymethod

For Example, the following code access the EntityEntry of the department entity and sets its Entity State as Deleted

Some of the important Property & methods of the EntityEntry

Property/MethodPurpose
CollectionsProvides access to change tracking information and loading information for all collection navigation properties of this entity.
ContextGets the context that is tracking the entity.
CurrentValuesGets the context that is tracking the entity.
EntityGets the context that is tracking the entity..
OriginalValuesGets the original property values for this entity. The original values are the property values as they were when the entity was retrieved from the database.
StateGets or sets that state that this entity is being tracked in.
ReferencesProvides access to change tracking information and loading information for all reference (i.e. non-collection) navigation properties of this entity.
DetectChanges()Scans this entity instance to detect any changes made to the instance data. DetectChanges() is usually called automatically by the context to get up-to-date information on an individual entity before returning change tracking information. You typically only need to call this method if you have disabled AutoDetectChangesEnabled.
Collection(String)Provides access to change tracking and loading information for a collection navigation property that associates this entity to a collection of another entities.
Navigation(String)Provides access to change tracking information and operations for a given navigation property of this entity.
Property(String)Provides access to change tracking information and operations for a given property of this entity.
Reference(String)
Provides access to change tracking and loading information for a reference (i.e. non-collection) navigation property that associates this entity to another entity.
Reload()Reloads the entity from the database overwriting any property values with values from the database.

The entity will be in the Unchanged state after calling this method,

Entity States

As we mentioned earlier, the ChangeTracker tracks the Entity states of an entity using one of the following states.

  1. Added
  2. Deleted
  3. Modified
  4. Unchanged
  5. Detached

Added

When we add an entity to the context, then the ChangeTracker sets the status as Added. It indicates that the entity exists in the context, but does not exist in the database. The DbContext generates the INSERT SQL query and insert the data into the database when the user invokes the SaveChanges method. Once the SaveChanges is successful, the state of the entity changes to Unchanged

In the following example shows the Entity State before and after SaveChanges.

Best Entity Framework Core Books
The Best EF Core Books, which helps you to get started with EF Core  

Unchanged

The property values of the entity have not been modified since context retrieved it from the database. The SaveChanges ignores this entity. The tracker also sets the State as Unchanged after a successful SaveChange as you can see it from the previous example.

Modified

The entity state becomes Modified, when the user makes changes to the entity. It also indicates that the entity exists in the database. The DbContext generates the update SQL Query to update the entity in the database. Once the SaveChanges is successful, the state of the entity changes to Unchanged

In Connected Scenario, the Entity framework Core also keeps track of the changes made to the properties of the entity. The context updates only those columns whose values are modified.

Deleted

The Deleted entity state indicates that the entity is marked for deletion, but not yet deleted from the database. It also indicates that the entity exists in the database. The DbContext generates the delete SQL Query to remove the entity from the database. The DbContext removes the entity from the context once the delete operation succeeds after the SaveChanges. I.e if you check the status after SaveChanges you will find it as Detached.

Detached

The Detached entity state indicates that the DbContext is not tracking the entity.

Attach

Entity Framework Core Attach method allows us to attach an Detached entity to context and start tracking it. In the following code, we are attaching two entities (Department1 & Department2). Note that in Department2 we have set the value of DepartmentID, which is a Primary Key. Notice that after the attach, the entity with a primary key is set as Unchanged, while the entity without a primary key is set as Added.

You can also attach an detached entity to the context just by setting entity state to anything other than Detached

Detach

You can set the entity state as Detached to detach an entity from the context.

References

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top