Our shop has been looking for a way to simplify the interaction between our domain layer and data layer. The data layer uses typed datasets for all its operations. When it retrieves data, it populates a dataset; when it stores data, it checks the DataRowState of all rows in the dataset, and calls the appropriate stored procedure to insert, update, or delete the data. The domain layer then uses dataset elements as the in-memory backing store for properties and collections. A collection typically uses a DataTable, for example, and a collection member would use a DataRow in the DataTable.
This arrangement has some advantages:
- Between requests, domain objects can cache their state in session by caching a dataset.
- DataRowState can inform the logic about which CRUD operation to perform on a DataRow. Unmodified data can also be skipped over, yielding improved efficiency.
- We have considerable freedom in designing domain classes. We can make a property read-only, for example, if it corresponds to an immutable database field, such as an identity column.
This arrangement also has a big disadvantage, however. We end up with lots of properties that look like this:
public string Phone
{
get { return dr.PHONE; }
set { dr.PHONE = value; }
}
This property's one and only use is to map a domain attribute (an entity's phone number) to a particular field in a DataRow (dr). Our domain layer has hundreds of these pass-through properties, which are a very verbose and not especially readable way of mapping between the domain and data layers. So we've been looking for a better way to handle this mapping.
Along comes the .NET Entity Framework (EF), which provides a tool that creates a domain-to-data map in XML format. Our first reaction was: this is just what the doctor ordered! And supported by Microsoft, to boot.
On closer examination, though, the EF toolset has some growing up to do before we could consider using it in our web applications. It can generate only public get/set accessors in the entity domain model (EDM) classes, for example. You cannot make a property read-only, or internal/protected/private, or virtual. You cannot map a non-generated property to a database field. And programming in a straitjacket was not what we had in mind for a new approach.
Second, EDM classes generated by EF do not have any supported way to cache their state. A Microsoftie is working on a tool ("Perseus") that can serialize the state of an entity using an EntityBag<T> instance, but it seems somewhat incomplete (and definitely not supported) at the moment. Since our web apps do cache domain entity state, adopting the EF right now would entail an important risk.
What alternatives exist? We can license DevForce EF, which is built on top of the EF and seems to offer pretty much everything that it lacks. Or we can try NHibernate, an open-source .NET port of the Hibernate tool which is quite popular in the Java development world.
Or maybe we can just wait for the EF to mature. Microsoft has big plans for the EF, and intends to make REST-oriented web services, Reporting Services, workflows, etc. EDM-aware. So an EF investment today can yield important dividends in the future.
Even though I cannot render a definitive answer, I hope that this discussion will help readers make an informed discussion about their ORM choices in the .NET world. What do you think? Leave a comment with your insights or questions!