Database Reference
In-Depth Information
8-7. Manually Synchronizing the Object Graph and the
Change Tracker
Problem
You want to control manually the synchronization between your POCO classes and the Change Tracker.
Change Tracker has access to the information that Entity Framework is storing about the entities that it is
tracking. This information goes beyond the values stored in the properties of your entities and includes the current
state of the entity, the original values from the database, which properties have been modified, and other data.
The Change Tracker also gives access to additional operations that can be performed on an entity, such as reloading
its values from the database to ensure that you have the latest data.
There are two different ways that Entity Framework can track changes to your objects: snapshot change tracking
and change-tracking proxies.
Snapshot Change Tracking
POCO classes don't contain any logic to notify Entity Framework when a property value is changed. Because there
is no way to be notified when a property value changes, Entity Framework will take a snapshot of the values in each
property when it first sees an object and store the values in memory. This snapshot occurs when the object is returned
from a query or when we add it to a DbSet. When Entity Framework needs to know what changes have been made,
it will scan each object and compare its current values to the snapshot. This process of scanning each object is
triggered through a method of Change Tracker called DetectChanges .
Change-Tracking Proxies
The other mechanism for tracking changes is through change-tracking proxies , which allow Entity Framework to
be notified of changes as they are made. Change-tracking proxies are created using the mechanism of dynamic
proxies that are created for lazy loading, but in addition to providing for lazy loading, they also have the ability to
communicate changes to the context. To use change-tracking proxies, you need to structure your classes in such a way
that Entity Framework can create a dynamic type at runtime that derives from your POCO class and overrides every
property. This dynamic type, known as a dynamic proxy , includes logic in the overridden properties to notify Entity
Framework when those properties are changed.
Snapshot change tracking depends on Entity Framework being able to detect when changes occur. The
default behavior of the DbContext API is to perform this detection automatically as the result of many events on
the DbContext. DetectChanges not only updates the context's state management information so that changes can
be persisted to the database, but it also performs relationship fix-up when you have a combination of reference
navigation properties, collection navigation properties, and foreign keys. It's important to have a clear understanding
of how and when changes are detected, what to expect from them, and how to control them.
The most obvious time that Entity Framework needs to know about changes is during SaveChanges, but there
are many others. For example, if we ask the Change Tracker for the current state of an object, it will need to scan and
check if anything has changed. Scanning isn't just restricted to the object in question either—many of the operations
you perform on the DbContext API will cause DetectChanges to be run. In most cases, DetectChanges is fast enough
that it doesn't cause performance issues. However, if you have a very large number of objects in memory or you are
performing a lot of operations on DbContext in quick succession, the automatic DetectChanges behavior may be a
performance concern. Fortunately, you have the option of switching off the automatic DetectChanges behavior and
calling it manually when you know that it needs to be called. Failure to do this can result in unexpected side effects.
DbContext takes care of this requirement for you, provided that you leave automatic DetectChanges enabled. If you
switch it off, you are responsible for calling DetectChanges for poorly performing sections of code and to reenable
it once the section in question has finished executing. Automatic DetectChanges can be toggled on and off via the
DbContext.Configuration.AutoDetectChangesEnabled Boolean flag.
 
Search WWH ::




Custom Search