Entity Framework provides ability to track the changes made to entities and their relations, so the correct updates are made on the database when the SaveChanges method of context is called. This is a key feature of the Entity Framework.
The Change Tracking tracks changes while adding new record(s) to the entity collection, modifying or removing existing entities.
Then all the changes are kept by the DbContext level.
These track changes are lost if they are not saved before the DbContext object is destroyed.
DbChangeTracker class gives you all the information about current entities being tracked by the context.
To track any entity by the context, it must have the primary key property.
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.
using (var context = new UniContextEntities()) { context.Configuration.AutoDetectChangesEnabled = true; }
Let’s take a look at the following example in which the students and their enrollments are retrieved from the database.
class Program { static void Main(string[] args) { using (var context = new UniContextEntities()) { context.Configuration.AutoDetectChangesEnabled = true; Console.WriteLine("Retrieve Student"); var student = (from s in context.Students where s.FirstMidName == "Ali" select s).FirstOrDefault<Student>(); string name = student.FirstMidName + " " + student.LastName; Console.WriteLine("ID: {0}, Name: {1}", student.ID, name); Console.WriteLine(); Console.WriteLine("Retrieve all related enrollments"); foreach (var enrollment in student.Enrollments) { Console.WriteLine("Enrollment ID: {0}, Course ID: {1}", enrollment.EnrollmentID, enrollment.CourseID); } Console.WriteLine(); Console.WriteLine("Context tracking changes of {0} entity.", context.ChangeTracker.Entries().Count()); var entries = context.ChangeTracker.Entries(); foreach (var entry in entries) { Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name); Console.WriteLine("Status: {0}", entry.State); } Console.ReadKey(); } } }
When the above example is compiled and executed you will receive the following output.
Retrieve Student ID: 1, Name: Ali Alexander Retrieve all related enrollments Enrollment ID: 1, Course ID: 1050 Enrollment ID: 2, Course ID: 4022 Enrollment ID: 3, Course ID: 4041 Context tracking changes of 4 entity. Entity Name: Student Status: Unchanged Entity Name: Enrollment Status: Unchanged Entity Name: Enrollment Status: Unchanged Entity Name: Enrollment Status: Unchanged
You can see that all data is only retrieved from the database that’s why the status is unchanged for all the entities.
Let us now take a look at another simple example in which we will add one more enrollment and delete one student from the database. Following is the code in which new enrollment is added and one student is deleted.
class Program { static void Main(string[] args) { using (var context = new UniContextEntities()) { context.Configuration.AutoDetectChangesEnabled = true; Enrollment enr = new Enrollment() { StudentID = 1, CourseID = 3141 }; Console.WriteLine("Adding New Enrollment"); context.Enrollments.Add(enr); Console.WriteLine("Delete Student"); var student = (from s in context.Students where s.ID == 23 select s).SingleOrDefault<Student>(); context.Students.Remove(student); Console.WriteLine(""); Console.WriteLine("Context tracking changes of {0} entity.", context.ChangeTracker.Entries().Count()); var entries = context.ChangeTracker.Entries(); foreach (var entry in entries) { Console.WriteLine("Entity Name: {0}", entry.Entity.GetType().Name); Console.WriteLine("Status: {0}", entry.State); } Console.ReadKey(); } } }
When the above example is compiled and executed, you will receive the following output.
Adding New Enrollment Delete Student Context tracking changes of 2 entity. Entity Name: Enrollment Status: Added Entity Name: Student Status: Deleted
You can now see that the status of enrollment entity is set to added, and the status of student entity is deleted, because new enrollment has been added and one student is removed from the database.
We recommend that you execute the above example in a step-by-step manner for better understanding.