NHibernate frente a EF 4.1+ [cerrado]

I am trying to decide the pros and cons of the 2 ORM primarily in this area.

  1. Compatibility with Sql Server 2008 R2 & 2012.
    • This is very important as we simply don't have the resources to debug poor support of existing MS technology stack.
    • Also planning ahead since 2012 is pretty much out and plans to migrate to it are in place.
  2. Support for .NET 4.0 and 4.5 (upcoming)
    • Again very important for pretty much the same reason above.
  3. Transaction handling and table hints eg. forcescan forceseek, read uncomitted.
    • A lot of times the query optimizer does its job well, other times I want the flexibility to tell it what to do.
  4. Support for conversation, self tracking attach & detach
    • This is somewhat fundamental. I hate to keep the session open for prolonged period. Especially in distributed computing/web farm environment.
  5. Ability to handle code first development, create and update schema without destroying data.
    • EF 4.1 seems to be wanting in this regard, although 4.3 is leap and bound better. Also liking the data annotation better than seperate mapping classes in NH. Reason being I want to be able to send in the class and from there be able to create persistence model without widening the method for the mapping classes.
  6. Support for IRepository pattern
  7. Support for LINQ
    • Somewhat tied to (6) above I want really good support for linq. I don't want developers to muck around with lower level implementation and getting ourselves stuck to one particular ORM
  8. Rendimiento
  9. Support for bulk CRUD operations, without having to load the data into the application layer. Eg. I want to increment all rows in a column of a particular table by 1. I don't want to load this up to memory, and increment the rows one by one. This would be crazy for such a simple operation. Linq2Sql used to have Magiq to handle this sort of thing, what does NH and EF have?
  10. Caching, eager loading, lazy loading, navigation properties.
    • Let me be frank I hate these things when done implicitly. Reason being it's hard to distinguish what is cached, stale from what is new. In EF I usually drop all navigation properties, because I don't want these properties loaded with top 5, because that's what the current operation needs, but further down the stream another developer attempts to do a count which will be inaccurate.
    • So my personal policy - all SOA shall be stateless unless there is a good reason otherwise. If you need referencing data, get it from persistence. It will be slower but the code will be more readable and flexible.
    • Similarly for caching. It is complex enough as it is in distributed environment, I want all caching to be very very explicit. If a developer wants to code against the cache, it should do so, not code against the ORM, and make it appear as if he is pulling fresh data from persistence when in fact he is getting stale data.
    • Now question is, does NHibernate have any concept/abstraction that would make caching, eager/lazy loading so much more explicit than the one currently available in EF. In this case I don't care much about ease of development, I care more about clarity and explicitness.

Also I don't care much for OSS vs. propietary argument. The team cannot afford the time to peek under the hood and start messing around with other people's code. I care more about the "it just works" angle than anything else.

preguntado el 12 de junio de 12 a las 20:06

Well written question, though I fear it's a bit open-ended for SO; questions here usually/often have some source code, and should lead to clear, practical answers. Perhaps it's better suited to Programmers.SE? -

5 Respuestas

While I wrote about some of these issues in otra pregunta, I think it's worth answering this one point by point.

  1. Both are compatible with all SQL Server versions
  2. Both are compatible with .NET 4.x. NH is still targeting 3.5, which is not an issue.
  3. Both have transaction handling. Neither supports query hints in the native query languages, but both allow you to use SQL.
  4. Both allow you to reattach disconnected entities. I personally do not think this is a good practice (I prefer passing DTOs around)
  5. Schema migration is more mature and flexible in EF. Mapping is way, way better in NH. It does have support for mapping with attributes, which is a lot more powerful than EF's equivalent, which you'll quickly find does not support even basic stuff (like specifying a decimal field's precision)
  6. You can implement your Repository on top of either one.
  7. Both support LINQ. EF supports a wider range of queries, at the cost of generating extremely inefficient ones sometimes. You shouldn't dumb down your development practices; each query method has its advantages and a good developer should know the options.
  8. Performance is usually better with NH because of its mapping flexibility and support for batching, caching, and DML statements
  9. EF does not support bulk (DML) operations. NH does, using INSERT/UPDATE/DELETE statements that are very similar to the SQL ones, but over the object model (for example, you can specify conditions using dot syntax instead of explicit joins)
    • EF does not support caching, period. There are some unsupported samples that are not ready for production. All caching in NHibernate is explicit (you specify which entities, collections and queries you want to cache, for how long, etc). It supports distributed caches like memcached, so it can take care of stale cache data too.
    • Both allow you to explicitly eager load references and collections. NH has, in my opinion, a better proxy design, which doesn't pollute your model with FKs (this is a long topic, you can post a followup question if you want). And as usual, you DO have more flexibility when specifying how each relationship must be loaded.

In a nutshell: NH is more flexible and better performing, hands down. EF has better migration support, a slightly easier learning curve and a more complete LINQ provider.

contestado el 23 de mayo de 17 a las 11:05

A lot of good answers but I find this one to be the most objective and relevant to the question asked. Thank you. - Alwyn

First of all, I prefer NHibernate under various aspects. Entity Framework misses something also in the version 5.0.

  1. Is very easy to add a new type in NHibernate, so if SQL Server 2012 has new types you can implement the relative dialect/provider, but the community is always working
  2. I know that the NH team is working on the support of FW 4.5, EF apoya it from the 5.0
  3. Using NH you can do all what you want
  4. NH supports the Merge method to re-attach an entity, EF also
  5. EF does not support naming conventions, NH does, I'm also writing an auto mapper based on DataAnnotations, aquí the link to the old version, wait 2 weeks for the new one
  6. Using NH or EF you can implement the Data Layer with the Repository and Unit Of Work patterns, I've to release also this package on NuGet
  7. EF fully supports LINQ, NH not but you can patch using an extension punto
  8. I think that performances are on the same level, NH better supports the secondary level cache so is easy to prevent hits to the database
  9. NH has an improved batching ASISTENCIA, I don't know about EF (specially the 5.0)
  10. NH has a better implementation of the extension points, so proxy/caching/logging are powerfull than EF, but in EF you can write a envoltura para obtener lo que necesitas

At the end, with NH is easier to implement DDD pattern, because the mapping is more flexible.

Respondido el 12 de junio de 12 a las 20:06

How is the NH mapping more flexible? I've found the EF 4 fluent API to be very flexible, especially since its defined separate from the entity classes. - jrummell

@MatteoMigliore I like that you brought up wrapper support that was really good to know! But yes, please clarify how is it that NH is more flexible than EF? EF Pretty much allows you to modify the edmx and do mapping anyway you see fit, same from code first. - Alwyn

The mapping in NH can be made in a various (multiple) ways. Lee the posts of Fabio Maulo about mapping. If you are interested, wait for my package of the auto mapper based on DataAnnotations to fast switch between NH and EF and viceversa. - Mateo Migliore

@MatteoMigliore - I'm interested in your automapper, as a possible replacement for Fluent NHibernate. Can you point me to docs, or a blog post with simple code examples? - tom bushel

@TomBushell I published an old version on Nuget. I've to publish the new version in two weeks, with improvements to automatically map all and to use with DDD, waiting for it you can also try Ajustarse by Fabio Maulo. - Mateo Migliore

You could use bltoolkit ;) -> http://www.bltoolkit.net/Doc.Linq.ashx

Just take 2 minutes to read this -> http://www.bltoolkit.net/Doc.LinqModel.ashx

But in short

  • extremely good Linq support
  • DML operations (nr 9)
  • great performace / bulk support
  • great generated Sql
  • enum support ;-)
  • no lazy loading / entity tracking / special magic caching, you now these things that usually cause problems
  • No magic features -> less abstraction -> less leaks -> less troubles -> smaller learning curve

btw it does nr 3, it has attributes TableFunction & TableExpression to support table-valued UDF, hints, and other around table decorations. So you can write your own extension methods to use in your Linq-statements for example

[TableExpression("{0} {1} WITH (TABLOCK)")]
public Table<T> WithTabLock<T>()
    where T : class 
    return _ctx.GetTable<T>(this, ((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(T)));

y entonces

using (var db = new TestDbManager())
    var q =
        from p in new Model.Functions(db).WithTabLock<Parent>()
        select p;


Sample DML operation

    .Where(e => e.Title == "Spectre")
    .Set(e => e.Title, "Commander")

Respondido el 13 de junio de 12 a las 14:06

You don't want either of them. You're not going to be able to specify arbitrary table hints, and it won't be anywher near as flexible as you want it to be.

If all those are requirements, there is no ORM on the planet that will meet them.


Based on your comment. nHibernate will give you the most power, but at the cost of increased complexity in setting up your model. There are some tools that might help, but each has it's plusses and minuses.

EF is easier to configure and use, but less powerful. nHibernate is the opposite. You have to choose between power and complexity.

BTW, regarding Bulk operations and what not, you can just issue SQL directly from the framework for such operations. Or call a stored proc.

Respondido el 12 de junio de 12 a las 20:06

No I'm going to pick the least of the 2 evil. Put it that way. - Alwyn

Thanks, but I need details. I hate untoward complexity and I need substantiating argument for why the complexity is there. The above are things that I look for I want to know how the complexity will help me reach that goal. - Alwyn

@Alwyn - I don't really understand what you mean. You need substantiating argument for why the complexity is there? It's there because that's the way they built it. nH has grown and evolved over time and most of it's earlier practices were rolled forward. They could have built nHibernate in a way similar to EF, but they didn't, and the only reason why is beacuse they have always done it the way they do it. There have been numerous attempts to bring nH into modern configuration mechanisms, some of them even gaining some hold in the core FW. In the end, though. Configurability = complexity. - Erik Funkenbusch

@Alwyn - It's not constructive to ask why something is the way it is, it just is. The question is whether you are willing to use it the way it is. nH gives you lots of flexibility, but you're going to be writing lots of XML, or trying to make fluent nH work. or any number of other side-projects. - Erik Funkenbusch

please don't take offense at my response I appreciate your time and your reply, but I was looking for more of a point by point comparison similar to Matteo's answer above. I don't have a legacy system, I just want to know which of the frameworks meet my needs better. And those needs are detailed above. p.s. I don't want developers to write sql directly, it defeats the point of having an ORM. - Alwyn

Just to add to other answers...

ricardo peres wrote a very good, unbiased comparison of NHibernate and Entity Framework few days ago. It might help you in your research.

Lo puedes encontrar aquí: http://weblogs.asp.net/ricardoperes/archive/2012/06/07/differences-between-nhibernate-and-entity-framework.aspx

Respondido el 12 de junio de 12 a las 21:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.