The DbContext in Entity Framework Core includes the ChangeTracker class in
Microsoft.EntityFrameworkCore.ChangeTracking
namespace which is responsible of tracking the state of each entity retrieved using the same DbContext
instance. It is not intended to use it directly in your application code because it may change in future versions. However, you can use some methods for tracking purpose.
The
ChangeTracker
class in Entity Framework Core starts tracking of all the entities as soon as it is retrieved using DbContext
, until they go out of its scope. EF keeps track of all the changes applied to all the entities and their properties, so that it can build and execute appropriate DML statements to the underlying data source.
An entity at any point of time has one of the following states which are represented by the enum
Microsoft.EntityFrameworkCore.EntityState
in EF Core.- Added
- Modified
- Deleted
- Unchanged
- Detached
Let's see how the
EntityState
is changed automatically based on the action performed on the entity.Unchanged State
First, all the entities retrieved using direct SQL query or LINQ-to-Entities queries will have the Unchanged state.
public static void Main() { using (var context = new SchoolContext()) { // retrieve entity var student = context.Students.First(); DisplayStates(context.ChangeTracker.Entries()); } } private static void DisplayStates(IEnumerable<EntityEntry> entries) { foreach (var entry in entries) { Console.WriteLine($"Entity: {entry.Entity.GetType().Name}, State: {entry.State.ToString()} "); } }
Output:
Entity: Student, State: UnchangedAdded State
All the new entities without key property value, added in the
DbContext
using the Add()
or Update()
method will be marked as Added.using (var context = new SchoolContext()) { context.Add(new Student() { FirstName = "Bill", LastName = "Gates" }); DisplayStates(context.ChangeTracker.Entries()); }
Output:
Entity: Student, State: AddedModified State
If the value of any property of an entity is changed in the scope of the
DbContext
, then it will be marked as Modified state.using (var context = new SchoolContext()) { var student = context.Students.First(); student.LastName = "LastName changed"; DisplayStates(context.ChangeTracker.Entries()); }
Output:
Entity: Student, State: ModifiedDeleted State
If any entity is removed from the
DbContext
using the DbContext.Remove
or DbSet.Remove
method, then it will be marked as Deleted.using (var context = new SchoolContext()) { var student = context.Students.First(); context.Students.Remove(student); DisplayStates(context.ChangeTracker.Entries()); }
Output:
Entity: Student, State: DeletedDetached State
All the entities which were created or retrieved out of the scope of the current
DbContext
instance, will have the Detached state. They are also called disconnected entities and are not being tracked by an existing DbContext
instance.var disconnectedEntity = new Student() { StudentId = 1, Name = "Bill" }; using (var context = new SchoolContext()) { Console.Write(context.Entry(disconnectedEntity).State); }
Output:
Detached
In the above example,
disconnectedEntity
is created out of the scope of DbContext
instance (context). So, it is in the Detached state for the context.
No comments:
Post a Comment