The hidden assumption of EF 4 self-tracking entity
recently I was diving into the Entity Framework self-tracking entity T4 and its generated code.
doing so I was finding some interesting assumptions made about the entity behaviors.
this post will illuminate some of those assumptions.
Background
EF self tracking entity is one of the major enhancement of EF 4.0,
it is a disconnected model (similar to the old DataSet) which enable tracking
the entity state (Added, Modified, Deleted and Unchanged) while the entity
is detached from the EF ObjectContext.
the code snippet of this post will refer the following very simple edmx:
Assumptions
1st assumption
by default the tracking is disable (ChangeTrackingEnabled = false).
2nd assumption
trying to change the entity state while the tracking is disable
- var p = new Person();
- p.ChangeTracker.State = ObjectState.Unchanged;
will have no affect on the entity state (the state will remain Added which is the default
state for new entities).
the following snippet shows the code of the State property:
- public ObjectState State
- {
- get { return _objectState; }
- set
- {
- if (_isDeserializing || _changeTrackingEnabled)
- {
- OnObjectStateChanging(value);
- _objectState = value;
- }
- }
- }
3rd assumption
the entity enable the tracking after deserialization.
- [OnDeserialized]
- public void OnDeserializedMethod(StreamingContext context)
- {
- IsDeserializing = false;
- ChangeTracker.ChangeTrackingEnabled = true;
- }
4th assumption
MarkAsAdded, MarkAsModified, MarkAsDeleted and MarkAsUnchanged all enable the trucking.
- public static T MarkAsAdded<T>(this T trackingItem) where T : IObjectWithChangeTracker
- {
- trackingItem.ChangeTracker.ChangeTrackingEnabled = true;
- trackingItem.ChangeTracker.State = ObjectState.Added;
- return trackingItem;
- }
5th assumption
State = ObjectState.Unchanged, MarkAsUnchanged and AcceptChanges
has different behaviors:
in general State property: is only changing when tracking is enabled,
MarckAsUnchanged: enable the tracking and
AcceptChanges: clear the original values, enable the tracking and
reset the relationship tracking (added and removed related entities).
- public ObjectState State
- {
- get { return _objectState; }
- set
- {
- if (_isDeserializing || _changeTrackingEnabled)
- {
- OnObjectStateChanging(value);
- _objectState = value;
- }
- }
- }
- public static T MarkAsUnchanged<T>(this T trackingItem) where T : IObjectWithChangeTracker
- {
- trackingItem.ChangeTracker.ChangeTrackingEnabled = true;
- trackingItem.ChangeTracker.State = ObjectState.Unchanged;
- return trackingItem;
- }
- public void AcceptChanges()
- {
- OnObjectStateChanging(ObjectState.Unchanged);
- OriginalValues.Clear();
- ObjectsAddedToCollectionProperties.Clear();
- ObjectsRemovedFromCollectionProperties.Clear();
- ChangeTrackingEnabled = true;
- _objectState = ObjectState.Unchanged;
- }
Summary
the self tracking entity is a fairly young concept in the EF world
and we can expect that it will keep changing.
as I was reading in one of the Harry Potter’s book
"do not trust anything you cannot understand", so be aware of that
assumption and use it well.