Like many people on this forum, I have been beating my head against my desk trying to use Self-Tracking Entities in a real-world scenario. I have been working on a set of T4 templates that generate an entire 7-Tier, WCF REST-enabled application, and I have made a bunch of progress. Until I had to start updating existing entities through my Business Logic assembly, and not through WCF. I had experimented for the better part of two months, to no avail. For example, I tried initializing the ObjectChangeTracker with tracking on by default. But that just considered every object as "Added", even if it was just being loaded from the DB.
And then today, the answer hit me. The code decorated with the [OnDeserialized] attribute in the STE T4 template is the one that does all the magic... so why only call it from there?
To fix it, add the following line of code at Line 291 of your Types.tt file:
public void StartTracking()
{
if (_changeTracker == null)
{
_changeTracker = new ObjectChangeTracker();
}
_changeTracker.ChangeTrackingEnabled = true;
this.InitializeMembers();
}
And change the OnDeserializedMethod (which starts at line 310) to this:
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
this.StartTracking();
}
Now, before you want to manipulate an object (like setting a property), make sure you call object.StartTracking(); Then, when your update method calls the following lines of code:
entityManager.EntitySet.ApplyChanges(response, EntityChangeTrackerAdapter.GetSelfTrackingEntityInfo);
entityManager.SaveChanges();
(you ARE calling those methods, right?), the ObjectChangeTracker will have the information it needs to do its job.
Maybe you all figured this out already. I don't know. I feel pretty dumb that it took me this long to figure it out. But I hope this tip helps other noobs like me save what remains of your hairline.