Missing NHibernate features in Entity Framework

Recently I blogged about migrating to EF from NHibernate and how easy it is to create fully encapsulated models mapped to EF. In this particular project, migrating was relatively painless, as it was a fairly new schema and quite amenable to code-first mapping in EF. The migration was successful in that I didn’t have to undo it and there were relatively few changes that I had to make to the underlying model.

However, there are still reasons why I’d stick to NHibernate, mainly around missing features that exist in NHibernate but don’t exist (yet) in Entity Framework. How important these features are varies from project to project, so while one project might be best using a micro-ORM, one might be best using NHibernate or EF. My punch list of missing features (so far):

A pretty long list to be sure, but not all of these items carry equal weight on any given project, and many of them are available via workarounds or extensions to EF (like the EntityFramework.Extended project). But what about NHibernate? What does EF have (that’s actually useful) but NHibernate doesn’t?

  • Anything moderately interesting with LINQ
  • Migrations
  • Async

Those aren’t small features, so while you might be slightly annoyed by a lack of bidirectional one-to-one mapping, not having async might be a big deal for you.

This is a somewhat hasty list generated from projects in which I’ve actually used these NH features in production, but is certainly not an exhaustive list. Let me know in the comments what I’ve missed!

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in EntityFramework, NHibernate. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Just some more:
    - Query batching (both inserts and selects)
    - 5 querying APIs (LINQ, HQL, Criteria, QueryOver and SQL)
    - 10+ key generator strategies
    - Lazy loading of properties
    - Several strategies for optimistic concurrency control (version, TIMESTAMP column, dirty columns, all columns)
    - Support for several databases out of the box
    - Collection filters

    • Bob

      - it has `5 querying APIs`, but none of them are as mature as LINQ to Entities of EF.
      - EF also has concurrency control.
      - ‘Support for several databases out of the box’ have you ever tried to query from date1 to date2 using its SQL_CE driver? Does it work?

      • Really? I’d say HQL and Criteria (at least) are far more mature, specially since they were ported from Java ~10 years ago.
        EFCF only has concurrency control for SQL Server’s ROWVERSION, not, for example, for Oracle’s ORA_ROWSCN. NH also has versions as numbers and datetimes.
        I have used NH with several other databases, from SQL CE to Azure, and, yes, it works.

      • By the way, Bob, this is by no means a religious war! :-)
        I do use (and like) Entity Framework Code First, and it clearly has stronger points.

    • - Ability to register extension methods that will map to database functions and to call them transparently through LINQ
      - Ability to register database functions for HQL
      - Executable HQL (database-independent inserts, updates and deletes)

  • Nikolai Mynkow
    • hazzik

      The problem with Ricardo’s approach that you can not use these fields in linq-queries.

  • Bob

    - for “One-to-one mapping”, try http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first-part-5-one-to-one-foreign-key-associations.aspx .
    - for “Schema generation”, try ef migrations (http://msdn.microsoft.com/en-us/data/jj591621.aspx).
    - for “Session.Load instead of mapping the FK separately”, try disconnected behaviors of EF, such as Attach and EntityState.Modified (http://msdn.microsoft.com/en-us/data/jj592676.aspx).
    - for “Computed columns (not defined in SQL server)”, try [NotMapped] attribute.

  • chester89

    Last time I checked, EF migrations was quite buggy.
    ORM doesn’t need migrator tool, because migrations are orthogonal to mapping, it’s about database schema.
    That being said, currently I use NHibernate + FluentMigrator on a couple of projects, and it’s MUCH simpler than EF.

  • gleb Chermennov

    Last time I checked, EF migrations was quite buggy.
    ORM doesn’t need migrator tool, because migrations are orthogonal to mapping, it’s about database schema.
    That being said, currently I use NHibernate + FluentMigrator on a couple of projects, and it’s MUCH simpler than EF.

    • Mike Cole

      What specifically is buggy about EF migrations? I’ve been using it with great success and with the exception of some merging issues (which has a fix promised) it’s been very helpful.

  • Bob
    • bdaniel7

      There are less commits for NH because the project is already mature while EF is still “under active development”. As far as I’m concerned, EF is still a beta product.

      • That will change soon, word is, EF 7 is a complete rewrite… :-)

  • hazzik

    Encapsulated collections with EntityFramework and DelegateDecompiler


  • bdaniel7

    Merge Disconnected Object Graph https://entityframework.codeplex.com/workitem/864

    Try to save a Chemical -> Isopleths -> IsoplethLevels by just setting .State = context.Entry(chemical).EntityState.Unchanged

  • Pingback: End of Month Research Roundup – May 2014 | endjin blog()

  • Eduard

    Pessimistic concurrency is also missing in EF

  • Pingback: NHibernate移除了对Iesi.Collections类库的使用,并改进了对SQL Server 2012的支持 - 马开东博客()

  • Vladimir Khorikov

    Entity Framework looses completely if you want to follow DDD principles: http://enterprisecraftsmanship.com/2014/11/29/entity-framework-6-7-vs-nhibernate-4-ddd-perspective/

  • hbopuri
  • Frédéric Delaporte

    I believe NHibernate lazy loading batching ability is a powerful feature missing in EF.
    This feature is a great alternative to eager loading for solving n+1 loading performance issues when iterating over list of entites with lazily loaded children or parents.
    Eager loading cause you to add more lines of codes for specifying it at each request requiring it. Sometime it even causes you to add conditional logic when requests are shared among callers that do not have the same needs regarding associated entities. And generated SQL for many eager loading can get quite convoluted.
    While lazy-loading batching get enabled by a simple mapping parameter (batch-size) on associations or entities, retains lazy-loading advantages while keeping to a low level the number of SQL round-trips done when iterating other a collection of entities.

    Since nobody speaks about it while this post is one year old, am I missing something?

    • jbogard

      I didn’t know this feature existed is probably why, thanks for the heads up!

  • Alexander Petrov

    all http://www.nhforge.org links are dead, new site is http://nhibernate.info