NHibernate vs EntityFramework – Experience From the Real World

I got asked today what I considered in choosing NHibernate or Entity Framework. This is a modified version of my response.

General Function

Both are object relational mappers capable of working with POCO objects, ie objects that are built without any dependencies on their persistence store.

As ORMs, they implement Unit of Work, Repository and ObjectQuery patterns (see Fowler PPoEA). They resolve entity relationships and they both enable the mapping of type heirachies using Table per Hierarchy (TPH), Table per Class (or join subclass) (TPC) and Table per concrete type.

Entity Framework out of box does not support databases other than SqlServer|Express|CE. There are third party drivers available for other databases such as Oracle and MYSQL.

NHibernate out of box provides supports for SqlServer|Express|CE, Oracle, MySQL and many others.

NHibernate provides support for caching of entities, which is useful for global reference data or long running session scenarios. This caching is provided through pluggable providers, a number of which are provided with NHibernate and can work with SqlServer broker in a similar manner to a sql cache dependency.

Configuration

Entity Framework supports a database-first approach with an integrated designer for Visual Studio. This designer produces an XML file (EDMX) that describes the required mappings. The designer does not accommodate for the full range of mappings possible, which leave you having to deal with the somewhat cryptic XML file directly, parts of which can be safely edited without being overwritten by the designer.

The build action on the EDMX file is to generate the entity classes. The big improvement on EF 4 is that the t4 to create the classes is easily modified to produce the classes you want.

My personal opinion is that designers are more often a curse than a blessing, particularly for application of any real complexity. An IDE upgrade may be impossible, or you might modify the underlying XML file in such a way that it never works again, or perhaps the designer is just too sluggish. I don’t rate designers too highly.

The alternative to Database-first development is model or code first. In this mode, domain entities are coded and their relationship to underlying database tables described using either declarative attributes or a Fluent API. I have discussed the configuration of Entity Framework CodeFirst here. As a general rule, I would avoid using declarative attribute to define database mappings as this is coupling your entities to the persistence store.

There is no code generation with NHibernate. Instead you have write your domain classes and use XML files to describe how the database tables relates to the domain entities. These XML files are then read from a location or as a embedded resource by NHibernate at runtime to create the mappings. The XML schema is not that difficult to understand but being XML is feels a bit, say 2003 rather than 2011.

So these days most folk seem to be using FluentNhibernate. This is an open source companion project to NHibernate and enable the use of compile-time safe Fluently coded mapping classes to describe eahc classes mapping. An interesting feature of FluentNHibernate is the Automapping features, which uses conventions to map tables to classes without the need for any configuration by the developer.

Entity Framework does not support mapping to enums or other custom types. Database fields must map to scalar primitive .net types. NHibernate supports custom types through the IUserType interface.

API

Entity Framework has a smaller API than NHibernate and exposes less knobs and levers. For that reason, it is probably easier to “learn” but when you need greater control then the limitations of the API quickly surface.

NHibernate has many points for extensibility for example:

  • In the construction of the connection, which can be useful to set user session variables in the database
  • Caching, as already discussed
  • Interception of queries, inserts, delete and updates
  • Interception of object creation
  • Diagnostic logging with log4net

To the best of my knowledge, Entity Framework does not have any of these extensibility points.

On the other hand, with a larger API comes a steeper learning curve. For example, the NHibernate Session has the following methods: Save, Update, SaveOrUpdate, SaveOrUpdateCopy, Replicate and Merge, some of which have overloads that return different types.

Lazy or eager loading is a huge consideration, particularly with n-tier applications. Eager loading can kill you because you end up sucking down the whole database in a single call, but lazy-loading can leave you with n-select performance issues. Entity Framework feel really immature in this regards because you can only set the lazy loading behaviour for the entire context, not one an relationship by relationship basis. With NHibernate, you can configure the container so that parent objects are eager loaded and child collection are lazy-loaded, or mix it up to suit each case.

NHibernate allows greater specification of loading strategies. You can eager load using a join in an initial query or a subsequent select, and even the specify an optimal batch size on a select. None of these features are available with Entity Framework. A sub-select strategy is useful for preventing unnecessary queries for objects that are already in the session ,and is something evaluated on a case-by-case basis.

Both Entity Framework and NHibernate support Linq, although the implementation is different. In Entity Framework Linq queries against the database contact are passed to the native SQL linq provider while NHibernate Linq is translated into HQL or criteria in the session to create the sql. From an API perspective the feel is more or less the same.

In addition to Linq, NHibernate provides a QueryByObject API in which you pass in a object with properties you want matched set, and two other criteria APIs – ICriteria and HQL. With the multiple APi available, my advice is to choose one and use it consistently, preferably wrapped behind an application specific repository.

Another important area of difference is cascade specification and the attachment of detached entities. NHibernate allows you to specify whether a relationship should automatically cascade inserts, updates, deletes and deletes including orphins. EntityFramework on the other hand only allows you to turn the cascade delete specification on or off. In attaching detached instances, which is done in n-tier applications, NHibernate will automatically cascade the attachment of related objects and will perform the neccesary database queiers to work out what needs to be persisted to the database. EntityFramework will not cascade an attach, each relationship needs to be travsersed and attached explicitly. This is a bit cumbersome for large object graphs.

Both provide access to the raw sql connection for those cases where it is just needed.

Support

Entity Framework, produced and supported by Microsoft has the advantage over NHibernate in terms of developers being able to find answers to questions. The MSDN documentation for Entity Framework is relatively complete and there are many technical evangelists espousing the use of Entity Framework.

NHibernate on the other hand has not got a corporate sponsor, and the quality of it’s documentation is definitely a pain point for developers learning NHibernate. A the time of writing, many google searches for NHibernate throw up their old JBoss site however the current “home” of NHibernate is http://www.nhforge.org. This fact alone throws a lot of developers.

As previously stated, the API for NHibernate has a lot more knobs and levers than Entity Framework, and I think for that reason alone much greater emphasis should be placed on getting the documentation right. I demonstrated before the large API for simply saving an object. It requires a lot a fair amount of pain and experience to know what eahc of them does.

Entity Framework is less mature than NHibernate, and I believe that it has a number of releases to go before it is enterprise feature-rich. Each release represents an opportunity for breaking changes, which is a consideration. Alternatively, Microsoft may not develop EntityFramework further which would be creating a potential legacy application. On the other hand, NHibernate is a community project and has to date been successful without a commercial imperative.

Conclusion

I’ve covered a lot of stuff here based on my own real-world experience with both Entity Framework and NHibernate in n-tier applications. In a few words, I would say that Entity Framework is easier to learn but harder to control and extend to a complex scenario, so as the complexity of the domain increases I would lean more and more towards NHibernate configured using FluentNHibernate.

In any event, I really want to stress the importance of separating the dependencies on the ORM from the application code, either through the use an IOC container or application interfaces. It may be that NHibernate is a better choice for complex applications at the moment, it may not always be that way.

I would also look at the development team. Frankly, working with an ORM and domain classes is a whole different kettle of fish to coding transaction-script style services and records sets. It’s taken to a whole new level when multiple tiers come into play. Some developers find the transition too much and that needs to taken into account when choosing a development approach. I would recommend finding a mentor that can guide the team through the pitfalls that most definitely exist.

Lastly, in addition to implementing a number of useful enterprise patterns, above all an ORM is about reducing the complexity of mapping a complex object domain to a relational database. If the project is simple to start with, with little or no object-relational impedance, an ORM will only introduce complexity where none was required for no perceivable benefit.

kick it on DotNetKicks.com

About these ads
This entry was posted in Design Patterns, Entity Framework, NHibernate and tagged , . Bookmark the permalink.

10 Responses to NHibernate vs EntityFramework – Experience From the Real World

  1. Roman says:

    Very nice overview! I also prefer to use FluentNHibernate than Entity Framework.

  2. John blackwell says:

    I have been researching this for the better part of a day, this is the most unbiased, realistic outlook I have read to date, Excellent article.

  3. Chris Sullivan says:

    Thank you for your overview. I too have experience of both (as well as basic ADO .Net / DataSets).

    For me it is the last two paragraphs that I find most significant. Pragmatic programmers and team leads should be wary jumping on board with latest and greatest technologies without considering the impact and risk to the team and the project.

  4. Bob says:

    Very Good article, sums up everything I have been reading about EF and nHibernate for the last day or so. Now all I have to do is make a decision on which to use.

  5. Sergey says:

    Fantastic article, very helpful – thanks a lot.

    There is one more point for consideration when choosing EF vs. nHibernate: EF can query SSAS OLAP cubes ( via SSAS Entity Framework Provider – http://www.agiledesignllc.com/Products ), and nHibernate cannot. It is important if you have large data volume (> 2 million of records) but still need your queries to execute very fast.

  6. Great article. Like another commenter said, the last two paragraphs really said a lot for me. The project I’m working on has a data model that doesn’t justify the overhead of full ORM. When I do start a project that justifies an ORM, I’ll take the plunge and learn nHibernate.

  7. Thank you for overview. I use POCO + EF + T4 + Repository design pattern for my project and it’s a piece of cake !
    I didn’t try NHibernate, but in further phases i’m interested to try it out.

  8. Nazeel says:

    great article

  9. Phil says:

    We’ve used EF for a few months but rollback to NHIbernate. These are the reason behind our choice:
    - The SQL generated by Entity Framework on an Oracle Database is less than optimal (lot of sub-select, aggregate functions applied on children collection are doing full scan, etc.). We’ve plugged NHibernate in and with the same linq code, we got great SQL. As the ones any good developers would do.
    - Having only one API (linq) for EF, you are stucked when you cannot get Linq to do what you want to. Then, we see an advantage for NHibernate to have many APIs
    - With EF, you need to buy a commercial database provider for Oracle Support (yeah, Oracle will support EF enventually).

    Indeed, NHibernate documentation is pretty sparse. But a lot of users to help and an open source with test libraries.
    Speaking of tests. Unit testing our repositories through a real database is a game changer for us. So using an ORM, we got an out of the box solution to switch our database (Oracle to SQLite) under automated unit testing.

  10. Prasanna Hebbar says:

    Thanks for the wonderful article – seems to be an unbiased article.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s