The scene: a company division with no prior in-house experience using any ORM of any kind. A really, really legacy database-the kind with many composite keys, fields with mystery names, uneven use of enforced keys, etc. Currently, access done through ADO teamed with stored procs containing dynamic sql involving string concatenations (horrible for speed, security and my sanity among other things)
The mission? Given the constraint of not being able to change the underlying database aside from adding on some views, build a clean, modern app to eventually replace a legacy app that’s creating significant maintenance pain.
Early on, the team decided to lean toward use of an ORM-several team members had had positive past experience with ORMs, and it seems to be the way the industry was headed. However, that still left a choice-which ORM? The choice was quickly whittled down to NHibernate and Entity Framework. We ran two small parallel spikes, and ended up with a few thoughts about working with each:
First, we picked 3 or 4 tables to map to with both technologies, wrote up some simple classes, and then set about setting up persistence through an ORM-agnostic repository via both mappers.
NHibernate’s mapping files are relatively easy to read, but there’s no GUI to write them for you. It lets you write your classes and then work on your mappings separately afterward. The classes are clean POCO. NHibernate requires some code modification (virtual/overridable) and works better with some child-to-parent mappings that don’t seem like they should need to be there, but generally, modifications needed are minor. Repository is straightforward, and there’s lots of helper code online to do the legwork. Not tested, but it’s got sophisticated caching built-in.
Entity Framework was from Microsoft and had a GUI. The classes were autogenerated in one direction, from the database to the GUI to the classes… non-mapped properties caused errors-the proper place to put such artifacts was in a separate partial class file for the class-looking at the autogenned class, it was VERY clear you were not supposed to touch it, and probably not supposed to look at it.. this left the class spread across your partial and the gui. In addition, there were tight EF dependencies on these domain objects. Not to mention, after working with the GUI, I got the strong feeling that the GUI would not be able to handle complex scenarios, leaving us working with the raw verbose and complicated (and not really designed to be hand-edited) mapping xml. A pre-written class doesn’t seem to be able to be used easily-at least, we were exploring the usefullness of the gui, which left us to recreating the pre-written classes via the gui. It wasn’t clear if it was possible to mark a class as read-only, and code wouldn’t even compile if fields required in the DB were not mapped. Repository pattern was a bit more work-less guidance online… not sure if that’s because EF is so incredibly new, or because EF users are generally not as familiar with this pattern… in any case, it was a bit more tweaking to get things working through a moderately ORM-agnostic repository interface. No seamless caching yet-that’s slated for v2.
NHibernate was an industry leader, was fairly mature, had been around a few years (and a few MORE years if you counted Hibernate) and a team member (me) had experience using it in a high-profile production environment. No paid support available to speak of (not counting unknown companies here) but a truly responsive, helpful community with a product that is in active development… but then, NO backing company (not even Red Hat these days) … potential of giving fly-by-night appearance to non-techies as a result.
Entity Framework is brand-spanking new. If it were a car, it might still have temporary plates! It’s a 1.0 Microsoft product, with all that implies. Next version slated for 2010. If anything happens, Microsoft’s there for help, or (worst case) to receive a lawsuit. And it’s always easy to justify a Microsoft product.
It was a tough debate, but we ended up going with Entity Framework. Despite agreeing that NHibernate was the better technical solution, the team eventually concluded that having a backing company was extremely valuable for the organization, and that the GUI would be helpful for people coming into the project that were unfamiliar with ORMs.
The next morning, we set about doing some preliminary mapping. (ignore the DDD-related problems with this workflow for now, please)
- Yeah, that GUI is looking even more inadequate…
- Generated class and mapping files are THOUSANDS of lines long-this really sucks what with the inadequate GUI
- IT was REALLY easy to screw up the EF stuff so the gui couldn’t load-easiest way to deal was to redo the whole thing-I think we did that about 5 times that morning.
- It didn’t seem to deal well with the messy legacy db. Due to the db-first nature of EF, the messiness was going to leak through into our classes…
- We were going to be on the hook to support this thing-were we ready to do that?
By noon, we’d decided to switch to NHibernate. Cleaner code, clearer classes, and a team member with experience suddenly became a whole lot more compelling.
Working through those mappings has been a valuable, revealing process too. (more on that in a later post)
(Corrected: Thanks to Scott Bellware for the heads-up that even if you’re working on a VB project, it’s still POCO and not POVO, since the C stands for CLR, not C#.)