entity-framework-4data-access-layerobjectcontextself-tracking-entities

EF4 DAL design and the ObjectContext: Argument with co-worker


I work with a senior developer who is a guru .NET architect. We have had many constructive arguments over the last 6+ months and generally I concede defeat in most of our discussions. I have learned stacks from working with him. There is one design problem we are currently in disagreement with, however, and I would like some opinions/suggestions because he hasn't managed to convince me of his position, and I will stick to my guns until someone can give me evidence that I am wrong.

We use Entity Framework 4.0 and we use BOTH persistence aware AND Self Tracked Entities in different models. We started using Self Tracked Entities for tracking changes to Entity Graphs that we serialised/deserialised over the WCF wire to our Silverlight application. It works fantastically. We have also started using Self Tracked Entities for models that we are NOT taking across WCF, but many remain as persistent aware Entities/Models.

My co-worker believes that Entity Frameworks ObjectContext should be kept around for the shortest time possible. He insists that it should only be around for the length of time needed to do a query and the length of time needed to persist something. Any business work done with Entities should be done detached. For each Entity Model we have, we have a query class and a persistent class that are both IDisposable and have the ObjectContext at instance scope and have the query/persistence logic in methods. We use these query/persistence classes in our business logic rather than using the the ObjectContext directly in business logic. When these class instances are constructed so is the ObjectContext and when Disposed, so is the ObjectContext Disposed. These classes are like wrappers around our LINQ operations separating EF from the business logic and assisting with LINQ query re-use.

Now first consider non-Self Tracked Entities:

I understand why he wants this and the desire to not have a long running ObjectContext, but my problem is that he always wants even trivial business logic to be detached from the ObjectContext and the fact that we have a separate query and persistence context under our design means that there is no ObjectContext state tracking of Entities being used in our business logic. For non-Self Tracked Entities this means that if we modify Entities in our business logic we must also set the Modified state of the entities manually prior to persisting. This is a REAL pain when persisting complex graphs with multiple changes. Also I doubt we can do it manually as well as EF does it automatically.

For our Self Tracked Entities this situation is the same because tracking is only turned on when graphs are de-serialised and so when working WITHIN a service where the query was performed, detached from the Context, there is still no tracking with Self-Tracked Entities.

My question is, what is the best practice for Entity Framework use and how should an Entity Framework DAL be designed? How long should the ObjectContext be around? Should business logic always be done detached from the ObjectContext? If so how do we do state tracking when working detached from the ObjectContext? One option I am thinking about is converting ALL of our entities to Self-Tracked Entities and using some graph traversal code to traverse queried graphs and turn tracking on for all of the Entities in the graph so Self Tracking is turned on even when working service side (basically mimicking what happens when the Self-Tracked Entities graph is de-serialised)...

I am not proposing that we keep the ObjectContext around for long periods of time, but working detached between query and persistence and losing the benefits of the ObjectContext state tracking to me seems silly...we are losing one of the great benefits of EntityFramework...

Sorry for long post...any help appreciated.


Solution

  • Microsoft recommends that the ObjectContext be short lived, and my experience has led me to believe that the life-span of an ObjectContext should ideally correlate to the duration of a web-request / user operation.

    I made the mistake of trying to use a global, long-lived ObjectContext in a desktop application, and it was a total disaster. If you're going to implement things like caching, under/redo edit semantics, etc. then you should consider a design that uses ViewModel classes which are distinctly seperate from the underlying data entities. Use the EntityFramework to help you construct your Model object graph, then build the ViewModel from that. When you want to save changes, allow your ViewModel Repository to reconnect to the underlying entities, alter their properties and save changes. This allows for a more "cachable", flexible, ORM independant, unit-test-friendly design.

    In terms of change tracking, try not to think of it as a cheap "user-made-a-change" mechanism for the UI, but rather as an expensive mechanism for tracking which recently-created entities need to be considered when saving changes.