Replacing Entity Framework with NHibernate
By Rob Jones | August 17, 2010
A few weeks ago, we came to the conclusion that there are a few vital issues with Microsoft’s latest Entity Framework.
I had already discovered the limitations of the designer when working with large models. To my surprise this has been a known issue for a very long time, but there no improvements have been made with the release of Entity Framework 4.0. A guideline I’ve seen on MSDN says that models from about 125 entities and upwards should be split up. Ironically enough, there’s hardly any support for splitting a model in different parts and I would end up with editing my mapping files manually, because there’s no designer support once you go down this road.
However, there’s an even bigger issue that we ran into, while performing the most basic operations in our real world application. We had chosen to work with Self Tracking Entities, as it looked to be a perfect and simple solution for all our problems. Yeah, I know… we should have known better! I’ll give you a simple example, that has nothing to do with our real world application, but will give you a clear insight in the problems.
Consider the following scenario: we have a web page that shows a list of cats. Every cat has an owner (well that’s what the owner likes to think anyway). Let’s say we want to change the owner for a cat.
I would consider this just a very basic chore, easily be solved in a way like this:
public void UpdateTheCat(int catId, Owner newOwner)
{
Cat myCat = this.Cats.Where(c => c.CatId == catId).Single();
myCat.StartTracking();
// Update cat properties and eventually the owner.
myCat.Owner = newOwner;
using (IUnitOfWork uof = ObjectFactory.Create<IUnitOfWork<())
{
ICatRepository icr = ObjectFactory.Create<ICatRepository<(uof);
icr.Update(myCat);
}
}
Where the CatRepository Update method would do something like this:
public void UpdateCat(Cat myCat)
{
this.objectContext.ApplyChanges<Cat>(myCat);
this.objectContext.SaveChanges();
}
Well, this is simply not possible. No matter what I did, whenever I tried to update a Navigation Property in a detached object, I would get an exception telling me that there were duplicate key values in the ObjectStateManager. Apparently someone in Microsoft’s Entity Framework team has made this by design. You’re not allowed to simply update your object this way because it could be that both objects would have changed and the Entity Framework wouldn’t be able to resolve the conflict.
That’s an understandable design decision. What’s not so understandable is that they check if it’s the same object based on it’s reference (aka. memory pointer). So, if I fetch a cat object from the database and, at a later stage in my code, create a complete new cat with the exact same values then, apparently, it’s not the same cat! Purely from a technical point of view this is 100% correct, because my new cat is in a different part of the server memory. However, from a functional point of view it’s still the exact same cat.
So, simply updating objects or adding and removing objects from a collection becomes a huge pain in the backside. Of course Microsoft presents workarounds. But, that’s exactly what they are, workarounds. In our case the workarounds weren’t very useful either, so we were stuck.
Feeling very disappointed I set out to learn more about NHibernate. It didn’t take long before we discovered we could simply cross out a lot of the limitations from the Entity Framework. To our delight we discovered that the NHibernate session is light-weight enough to store in the HttpSession! This looks to be a major advantage for us! This means the session can keep tracking its own changes over multiple requests to the server!
More to come later…



