Persistence Ignorance: OK, I think I get it now.

Let me apologize up front for how long it has taken me to get back to this topic.  What I can say, though, is that in the intervening interval I have devoted real time to studying agile design principles and domain driven design.

Initially I thought that some of the requests for *complete* persistence ignorance were the products just of dogma rather than fully informed and reasoned arguments, but when so many people give such passionate feedback it was clear that I needed to investigate more before I could claim to have any sort of an informed opinion.  The product of my research is that I am now truly convinced of the importance of complete persistence ignorance for some scenarios.  As a result, the team is now working on a series of product changes aimed at ensuring that a later move to complete persistence ignorance will not be a fundamental breaking change. 

There's no question, though, that complete persistence ignorance comes at a price--both in the performance of applications built with "pure POCO", persistence ignorant domain models and as a result in the complexity of the entity framework which enables them.  The additional complexity of the framework is not just about enabling such applications to function but a product of the fact that the performance degradation which results means that the framework must support a spectrum of flexible options between complete persistence ignorance on one hand and prescriptive architectures which build some persistence information into the domain model to improve performance on the other hand.

To make this more concrete, we have identified 4 elements of the existing entity framework design which block persistence ignorance.  That is, 4 ways in which entities are currently required to have knowledge of the framework:

  1. They must store a copy of an EntityKey.
  2. They must provide change tracking notifications through a prescriptive interface.
  3. They must be decorated with a series of attributes which provide additional metadata.
  4. If they participate in relationships, the requirements are even more stringent as indicated by the requirement to implement the interface IEntityWithRelationships.

The first two requirements are enforced with the IEntity interface and must be addressed if we are to enable persistence ignorance at any point in the future.  In fact a series of key object services APIs currently .  At the same time each of these has significant performance implications.  Choosing not to store EntityKeys on the entities, for instance, means that navigating from an entity to the ObjectStateEntry which matches it either requires a brute-force search of the ObjectStateManager or for the ObjectStateManager to maintain a dictionary mapping from CLR reference to ObjectStateEntry which is a significnat expense.  Not supporting the change tracking mechanism means that the ObjectStateManager must cache a copy of the original values for each entity (all original values and they must be cache whether or not the entity is modified).

While I do believe that there are circumstances in which the loss of performance is a reasonable tradeoff for persistence ignorance, I also believe that for a great many applications, even where persistence ignorance is highly valued, there will come a time in the performance tuning process when one or another of these two compromises must be made.  As a result, we are working on replacing IEntity with two separate interfaces and making both of them optional--which means the object services API signatures will change from taking parameters of type IEntity to type "object" and the framework must support multiple mechanisms for each of these.

The 3rd and 4th issues are, on the one hand, harder to correct, but on the other hand things which can be corrected later.  At some point we will add an alternative mechanism for specifying metadata about the entity objects (thus freeing us from the hard requirement for attributes).  Similarly, we can envision ways to enable POCO collection and reference mechanisms for relationships which can be added later as a complement to the existing prescriptive EntityCollection<T>, EntityReference<T> and RelationshipManager classes.

So, to sum it all up, message received: persistance ignorance is needed, and we're now working to deliver it.  The first release of the entity framework likely will not have full support for it (there's just not enough time), but we will work to get into the first release the key changes which could not be made later so that the stage is set for the next release.

- Danny