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!

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

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 Entity Framework, NHibernate. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://weblogs.asp.net/ricardoperes Ricardo Peres

    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?

      • http://weblogs.asp.net/ricardoperes Ricardo Peres

        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.

      • http://weblogs.asp.net/ricardoperes Ricardo Peres

        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.

    • http://weblogs.asp.net/ricardoperes Ricardo Peres

      - 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.

      • http://weblogs.asp.net/ricardoperes Ricardo Peres

        Alex: that is a problem with non-public members, not my approach! :-) But protected properties can still be useful, if only meant to be used from inside the class or its inheritors.

  • 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.

      • http://weblogs.asp.net/ricardoperes Ricardo Peres

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

  • hazzik

    Encapsulated collections with EntityFramework and DelegateDecompiler

    https://gist.github.com/hazzik/c08eabc7dffdca83eb55

  • 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