Responding to how EF is better NH commentary…
My last post caused quite a bit of furor, and I decided that I wanted to respond to all the comments in a single place.
- EF has a designer, NHibernate does not.
This is actually false, NHibernate has multiple designers available for it. Active Writer (Free, OSS, integrated into VS), Visual NHibernate (Commercial, Beta) and LLBLGen (Commercial, forthcoming in early 2010). I would say that using a designer with NHibernate isn’t something that is very common, most people tend to either code gen the entire model and tweak that (minority) or hand craft the model & mapping. That isn’t for lack of options, it is because it is simply more efficient to do so in most cases. - EF is from Microsoft.
Yes, it is. That is a good point, because it reflect on support & documentation. Unfortunately, the fact that this was one of the most prominent reasons quoted in the replies is also interesting. It says a lot about the relative quality of the products themselves. Another issue with a data access framework from Microsoft is that history teaches us that few data access methods from Microsoft survive the 2 years mark, and none survive the 5 years mark. RDO, ADO, ADO.Net, Object Spaces, Linq To Sql, Entity Framework – just to name a few. - Downstream integration.
That was mentioned a few times, as in integration with data services, WCF RIA, etc. I want to divide my comment to that into two parts. First, everything that exists right now can be use with NHibernate. Second, EF is supposed to come with reporting / BI tools in the future. Currently, everything that came up was easily usable with NHibernate, so I am not really worried about it. - In the Future it will be awesome.
Some people pointed out that Microsoft is able to allocate more resources for EF than an OSS project can. That is true to a point. One of the problems that Microsoft is facing is that it has to pay a huge amount of taxes in the way to create a releasable product. That means that it is typically easier for an OSS project to release faster than a comparable Microsoft project.
So far, I find it really interesting that no one came up with any concrete feature that EF can do that NHibernate can’t. I am going to let you in on a secret, when EF was announced, there were exactly two things that it could do that NHibernate could not. Both were fixed before EF 1.0 shipped, just because that fact annoyed me.
Are you telling me that no such thing exists for the new version?
Comments
Regarding, EF is from Microsoft and your '2 years mark', their releases are improvements and adaptations of newer constructs. That's a good thing, eh?
A sidenote (maybe irrelevant)
ADO.NET passed the 5 year barrier. After ADO.NET, every other MS technology based on or using ADO.NET.
And I think, to compare ADO.NET with NHibernate or Entity Framework is wrong. Because as I mentioned, they use it under the hoods, they are at different levels of abstractions.
Berke,
I am looking not on whatever you can still use it, I am looking into whatever this is what MS says you should use
In response to the 'microsoft is able to allocate more resources', that doesn't automatically means that it will be better in the future. It's largely dependent on which people get allocated to it. Quality counts, not quantity.
Well, IMHO that doesn't change that they are still at different layers/levels of abstractions.
Entity Framework uses ADO.NET, so by recommending EF, MS doesn't kill ADO.NET. It just promotes a wrapping layer over it. IDataReader (or whatever) will still be there.
(I hope, I didn't hijack this thread. Just wanted to point out something.)
Hey Oren,
So what were the two things that you adapted from EF into NH? Just curious.
If I knew NH more intimately (which is hard for me to do as I am still busy digging deeply into EF4 for the 2nd edition of my book), I might be better able to identify any positive things that EF can do that NH doesn't. Hopefully, some of the NH pros who are looking closely at EF4 will be able to respond.
I'm sure any list you provide of what NH does that EF doesn't will be a great spec for EF vNext. :)
julie
For me, it's about community.
It's always only been about community.
Where can I find the most resources?
Where am I most likely to successfully google for results?
Where is it reasonable to assume folks would know how to answer in forums?
Where will there be a lively blogging ecosystem I can continuously learn from?
Where will the most books be published?
Where is the most feedback taken from DevUsers and SuperUsers and put into the product?
Microsoft has the muscle needed to bring a V1 framework into all local developer communities around the globe and the online based ones.
More people --> Bigger community --> Richer Ecosystem --> That's where I'll be.
That's why, given a viable Microsoft framework and open source alternatives, I'll always consider the Microsoft one first.
That being said, a good community is wonderful, but if the product doesn't work (EF V3.5), it won't matter at all.
-- Justin
Julie,
One of the features was the ability to use multiple tables in a single entity definition.
The other... for the life of me I can't recall right now, I think it was something stupid & easily fixed, however.
And I am going to do NH to EF version post at the near future :-)
Does that hold for Dynamic Data aswell?
@Ayende
"I am looking not on whatever you can still use it, I am looking into whatever this is what MS says you should use"
This is what separates the men from the boys. The men KNOW what to use and dont care what anyone says to use.
I find the 'it will be awesome in the future ' argument laughable.
Where is the historical evidence of ms ever doing this?
Name one paradigm or framework ms have ever improved?
mstest or unity? I think not.
For what it's worth, we have to tell our clients (I work for a web hosting company) not to use NHibernate or they need to purchase a virtual/dedicated server because it will not run in medium trust.
That's one HUGE thing that Entity Framework can do that NHibernate cannot (out of the box, at least). Pretty frustrating because NHibernate would be our recommendation otherwise.
just reread my previous comment, and it came off as way snarkier than I intended. The ability to use ProxyGenerators definitely helps the issue, but it would be nice if NHibernate "just worked" out of the box in a medium trust environment.
Phil,
I got NHibernate to work pretty on medium trust. Yes, it's a pretty big deal if it doesn't just work. But, an updated castle dynamic proxy is the only thing I needed to do (I took the assembly from the one in ProxyGenerators). Well, it's against my local IIS 7 install without any modifications to the trust environment so YMMV.
The one important thing to realize is that NHIbernate has been around for a long time now and has started a small ecosystem of it's own. So in my mind, unless EF begins to offer a bigger return there's no real reason to switch. The support and community for NHibernate exist today, so there's no reason to wait for what ifs
@Paul cowan
asp.net webforms ;)
Patrick,
I believe so, yes.
Paul,
Remember magic V 3.0 ? That is what this is based upon
Phil,
OOTB, NHibernate can run with medium trust.
Justin,
Why are these community issues the deciding factor? If the ultimate goal is productivity (and if it isn't, then we're disturbingly off-track), then we adjust for our weaknesses to become stronger, if those strengths serve productivity.
The social and community aspect may (and only may) be a factor. Nonetheless, NH has a pretty large and mature community. You might not know where they congregate, but that is just as much a reflection of where you invest your own attention as a reflection of where the NH community locates itself.
There are more ways to participate in community and to succeed long term than merely following the herd.
The deeper issue isn't that the first and second versions of Entity Framework were insufficient, but that the mistakes made were amateurish and betrayed an incredible naivete about the problem domain on the part of the EF team. And this suggests that the EF team has an acculturated and internalized a-priori belief that it already knows so much that it has nothing to learn. The team was disabused of this dangerous vanity quite readily by the community of OO-over-relational storage veterans that the EF team had tried to represent itself as conversant with and a party to.
There's more to this issue of why the first couple of revs so readily promoted some of the most well-known mistakes in this field as desirable practices. The deeper issue is one of trend and of vanity. The issue is whether this predisposition in the EF team culture has been sufficiently rehabilitated to keep them from repeating the most obvious mistakes for their sense of entitlement to work in comfortable isolation.
Enough time hasn't yet passed to prove whether the EF team has disavowed the predispositions that continued to get it into software design and product design trouble to begin with. Even if the team has healed itself from this rotting vanity, it still has all the baggage of the software design negligence of the time still living in the product and still influencing the possible directions that future versions can take (forgoing a complete re-engineering a la WF, which arguably didn't work well without also re-acculturating the team).
I see your reasoning, and wonder if you recognize how much implicit fear is invested into it?
There are two kind of people in .NET world. The ones that likes the language and uses the framework and features following a regular OO development (people that could work in java, ruby, smalltalk, c, etc) and the ones that does whatever microsoft says, the people that are evangelized. Don’t forget .NET is full of people that worked a lot of time with VB6 and ASP 3.
When .NET cames, it added a pretty good feature, inheritance, and people could start thinking about it. The data access was solved with datasets, that worked a lot like recordset (from the api perspective). But microsoft always suggested to use typed datasets, so developers would use strong typed properties instead of strings. A small step for man, a giant leap for mankind.
Then linq-to-sql came, so you can have objects representing your tables. Each column is “mapped” to a property. Even those foreign keys, but you have also the actual association, so you don’t need to make another select! I think they are educating people and once the developers get used to it, they could remove the fk property from the class. Baby steps, again.
I know, for NH guys all this is trivial, but try to talk about mappings, first level cache, second level cache, inheritance mapping strategies, query cache, multiple databases support, query substitutions, lazy loading, batch size, fetching strategies, custom types, etc. with someone that still thinks from the database schema perspective. Come on, there are people that writes a stored procedure for a simple insert, just because there’s a myth about the stored procedure performance!
There’s not NH vs EF. There’s NH for those that work as community does and EF for the ones that goes to church every sunday morning.
"If I knew NH more intimately (which is hard for me to do as I am still busy digging deeply into EF4 for the 2nd edition of my book), I might be better able to identify any positive things that EF can do that NH doesn't"
Sorry Julie, I know you work hard on EF through your books, but I think that is part of the fundamental problem here: If I was to write a mvc based web framework, I'd take the mature existing framework and understand how it works and it's features... ie. Ruby on Rails. Then, based on that knowledge, I'd look at.... ie. asp.net mvc. With that I'd try to make sure the foundation of.. ie. asp.net mvc was built on the same principles that made the more mature product so good - ie. convention over configuration etc... I think it was a huge mistake to not make these POCO objects in version 1.
So with EF, which is really version 2 - even though MS is telling the world it's version 4 (why???... I think this is trying to hide something personally - why would you jump your version up 3 notches - you can't version something to a higher number to promote 'maturity'), and yet the EF community is still looking around saying 'ok, how can we make this more like NH in version 2'.
But from what I see in version 1 was just a move to try to get companies using stored procs to come to EF so they could continue to use the same stored procs in a different way. And yet if you override 'update' of a EF object, you have to also override insert, delete, etc... it's all or nothing... but I digress.
The purpose of this response is that I see, similiar to Bellware above, this lack of identifying where EF is short, coming out with it, making it clear, versus things like 'we're more than just an ORM'.
Everyone I know that has works with it says 'EF is version 1, we hope it improves, it took NH years to reach it's current maturity level, it will take EF awhile if it survives". NH is currently the preferred ORM, is very feature rich, covers even the fringe cases that comes from a community that is working in the field and knows what is needed on the job. That is one area, I'm not sure MS can really compete with - writing ORM's in labs and for books isn't the same as when you are sitting at a customer location looking at a legacy system that requires complexities with hilo generation, append only models, interception capabilities, strong unit of work capabilities... and on top of all that , a strong community that has tons of examples on how to pull of 'conversations' vs. 'per session' - how to use a ISession properly in a web app vs. windows app, etc...
I'd personally like to see more teams take on the approach I saw with the asp.net mvc team, I felt they listened to the community as best as possible, were very transparent in their releases and explanations on what they were attempting to achieve. More of that is a good thing. Actually it's what we have with NH today :)
I can only talk for myself - the single most important thing that EF has over NH is detailed documentation and tutorials for the person starting out.
I have been stuck in legacy city for the last few years without the leisure to spend the mind power on learning either. When the time did come, I spent over a week trying to find the "here is how to start with" type of article for NH (as the online community is VERY strong for NH). I could not (and really, still have not) find anything like that. Advanced information yes; old (3+ years old for v1) starting documents (that do not work with the current version at all) yes. But nothing to get me started with the current versions. For EF, the very first document was what I needed to get started. There was a tutorial that had me writing a working sample program with my legacy database in under a hour. That is hard to argue with - particularly to management that is looking to get a department up to speed quickly.
Honestly, I'm surprised in all this that the addition of a functional LINQ API is not considered a major feature?
LINQ is a strongly typed query language DSL baked into the language which gives you a 'natural and intuitive query api' with superior intelli-sense and re factoring support. We finally have the same 'convergence querying API' that can be used to query other data sources (i.e. Linq 2 Entities, Linq 2 Xml, etc) which allows knowledge transfer and the ability to familiarize with the one query API to rule them all.
Even though MS's track record has not been too stellar when it comes to Data Access technologies I honestly think LINQ and EF is here to stay as anyone else will have a tough time trying to surpass it with a better API / data access technology.
Personally I'm happy to forgo legacy technology and not have to touch the Session/Criteria API again as its clearly a result of an API that existed pre-LINQ designed to fit languages with defficiencies in their ability to express a natural query language.
NHibernate may eventually come with a mature LINQ provider but it will always have to support its legacy API which will dilute the amount of supporting resources and documentation available for it while at the same time hindering its ability to add new features.
In regards to a designer. It's still true NHibernate doesn't have a designer. I don't see why i have to use a 3rd party tool to use a 3rd party tool, when i could use a 3rd party tool that has a designer to begin with, or just use the EF which has a designer.
I find those points to be somewhat lame. (sorry if that offends anyone). If EF works for you, then great. Use it.
Lack of a designer built in doesn't matter to me. I generally dislike designers; that's a personal preference, just like preferring to have one built it is a personal preference.
EF being from Microsoft doesn't mean it's better. It means its a canned product. NH is oss and easily hacked up to your hearts content - but I don't recommend it because it's already an awesome ORM.
If you are waiting for downstream integration, you probably dont need it right now anyway. Otherwise you could build your own for anything you happen to find that doesn't already work with NH.
Again, if you are waiting for it to be awesome in the future... NH is awesome right now. And if the learning curve is intimidating (shouldn't be) then check out Fluent-NHibernate.
All this talk about the EF designer, but has anyone commenting here actually tried using the EF designer with a large model? It falls over, becoming so incredibly slow and unwieldy as to become virtually unbearable. I fail to see how the designer offers a true advantage.
I spent a lot of time using designers in my early days, but have since outgrown them. I suggest you do the same. We are programmers. We write code. You will do yourself and your customers a huge favor when you learn to solve problems more quickly using code rather than designers.
NHibernate needs better IDE support, a more unified community, and better documentation before it will be able to compete with any MS ORM solution. The barrier to entry is pretty high (IMO) for many people and/or organizations.
People are tired of XML editing (I see that every days with IOC Xml configuration) and they want a designer to do it faster.
Some people didn't know that they have to copy/paste the XSD in VisualStudio and "reference" it using XmlNamespace in their Xml. And the file type "nhibernate mapping" doesn't exist in the "New file dialog" in VisualStudio. Just because of these little things, beginners will not give a try to NHibernate.
The Xml editor of VisualStudio can check the structure and add intellisence thanks to the xsd, but doesn't check typo errors (mapping to a wrong property name, etc.) That's why a lot of people hate Xml and prefer to use "Fluent NHibernate" or such a thing.
But these points could be solved by adding some templates in VisualStudio in a "NHibernate installer", and installing also some "Reharper templates" as in the new Spring.net: www.springframework.net/.../vsnet.html#d4e9531
I think there're 2 types of Designers: for beginners who doesn't know how it works inside (as for EF), and people who need to generate a lot of "code" faster and reducing typo/syntax mistakes.
"More intelligent Xml editor" could help to do the mapping faster reducing mistakes, but it will be really cool to have a designer like the one in Eclipse:
The XML way (less intrusive, more verbose):
www.eclipse.org/.../...eClass-XML_viewlet_swf.html
The "Attributes" way (more intrusive, less verbose):
www.eclipse.org/.../...nnotations_viewlet_swf.html
Now, about the "It's not from Microsoft":
Why it couldn't be as in the Java World? Maybe because OpenSource Frameworks are supported by a huge and strong community (Apache Foundation for example) or by one or several companies (Who's supporting Hibernate? JBoss, a strong company. Who's supporting NHibernate? a perfect stranger to my boss's eyes).
I'm a part of ALT.Net France, and I wish ALT.Net could be a clone of "Apache foundation" for .Net. Maybe the "Alt.net" name will be as trusted as the Microsoft name? I'm dreaming... but it depends only on our efforts.
One of the things EF had at release at release time that NHibernate didn't was Linq i believe but I think Linq to NHibernate may have been in beta and has now been released so I don't see any reason to bother with EF. NHibernate is a much more mature framework.
@Mathias: the designer you linked to (of eclipse) is a good example why people hate designers: it's utterly cumbersome to add the mappings of several entities and properties as it takes a lot of clicking, mousing and fiddling with controls which is so time consuming that people really want to type it all in. The same goes for the visual diagram based designers like the one for EF and Linq to sql: very time consuming when you're dealing with any model that's bigger than northwind.
Designers therefore should be 'designed' (;)) to be less time consuming than typing in a textfile and at the same time offer more features than a textfile can do (that last point isn't too hard). So any designer which isn't geared to be used with hundreds of entities in one big model is not worth using, as such designer will take ages to set up a model.
I hate designers.
They require too much clicking to get what I want done.
They have zero flexibility in what I want from the generated code.
They generate far too much code than is useful.
They tend too crash in unexplainable ways in certain situations, and no way to ascertain why.
Many of the ORM related, tangle the object model too much with the data model.
@ Demis
Are you unaware of LinqToNH or are you just saying that it's not mature?
Wow..I really have to stop coming to this site. Your site has become the epitomy of "Magazine Advertising". Whats going to be next weeks artcle: "Lose 30 pounds in a week with 5 minutes a day?".
You would figure clicking on article entitled "What can EF 4.0 do that NHibernate can’t?" from an accomplished developer/architect/author would have more substance than to drive traffic so more profiler licenses can be sold and re-state how NHibernate is the God OR/M.
This isn't just for this article...another article you posted 2 weeks ago:
"How to Write MEF in 2 hours" ( ayende.com/.../...rite-mef-in-2-hours-or-less.aspx) was a complete waste of my time and another click WHORING title to an article with no substance.
Bart,
This is my blog, you don't like it, you hereby have my permission to stop coming here.
Bart, Ayende is slowly turning into another Jeff and Joel. Glorified writer, amateur programmer. Too busy rubbing his ego.
@ Bart, if you like EF more you can buy the profiler for that :)
@ Ayende, have you found a feature yet that EF has and NH doesn't? I can't find one in the comments here...
Lack of a designer doesn't bother me at all - too inflexible for my liking, but others (mainly web programmers) made a big push for Linq2SQL in our company mainly because of the designer.
We'd used NH 1.2 before and found the lack of documentation a major problem.
Fortunately, the person making the choice which way we went was me, and I'm a business logic developer, and hate graphical designers that tie you into a way of doing things. Microsoft also made the fortunate decision to dump Linq2SQL, EF 1.0 was just pointless, and NH had a basic Linq provider (this was actually really important to getting newer developers on board) so I managed to get the company to commit to NH.
I still cringe though everytime someone asks me an NH question I don't know, and I have to spend time on Google and the NH forums, to hunt through several blogs, and just experiment to find the answer. it's worse when you find something, try it, and it doesn't work (old documentation or just not complete)
Better or worse, the big thing EF will have is that its got Microsoft behind it and the guides about it will be better organised (MSDN) and plentiful. If the features are roughly comparable, then that will be the winner for most people I think.
Designers are a bit overrated, and even MS cannot be trusted to do the right thing by providing designer support. Just look at WPF. The "next greatest thing" from MS in the EF arena will probably leave developers in the same lurch as WPF.
When I first started with WPF if VS2k8 I was royally pissed that they didn't release a proper integrated designer. I stuck with Winforms as a result since I personally wasn't going to fork out extra cash for something I felt should have been provided in the first place. Now that I work somewhere where they use WPF & Silverlight, I've gotten a chance to work with Expression Blend, and still I'm left disappointed. It's "twitchy" and so damned slow to do trivial things, so I'm left hand-writing XML, and using Blend for relatively trivial tasks such as exporting XML styles.
This isn't to say that WPF isn't a really cool improvement over Winforms, I think it definitely is, but it does show that the useful "designer" isn't always going to be provided, even by MS, and it certainly isn't necessary.
Ultimately it's going to boil down to the type of developer, of which I would say there are two dominant categories:
The exploratory: These are developers that work in environments where they have the freedom to always look for the best way to get stuff done. They may use OSS, or commercial stuff from MS etc. Whatever best suits their current needs.
The spoon-fed: These are developers that work in more rigid environments where the focus is on "standards". They don't justify the time, cost, or risk of looking for the best solution, and rather are content that what's provided to them from the source (MS) is good enough for others so it's good enough for them.
Probably the right question will be "Why not use EF 4 and use NH instead", since everything else you use come from Microsoft.
I don't think arguement of which is better is important. Most developers won't do complete analysis themselves and will adopt a technology which suits them the most.
Must have really compelling reasons of using NH, if EF 4 works as they say it should(Didn't play with the Beta yet).
@Steve, that sounds like your trying to be a jack of all trades. The whole purpose of Blend is to give Designers something to Design in, so developers don't have to worry about what its going to look like.
The designer for WPF in VS08 does enough to get by without having to worry about the end result, because a designer can do all that later.
@NC: Fair enough, but I do end up doing much of the site/form design. Half of the companies I've worked for had dedicated business analysts, maybe three had dedicated testers, and only one had a dedicated designer.
@Dinesh: I'd say the compelling reason that NHibernate is used is that it was available two years ago based on a technology that was proven even earlier. If people have cut their teeth on NHibby, why would they swap it for EF? I use Visual Studio on a MS OS, and sometimes SQL Server. I also use Oracle, Resharper, NUnit, Moq, Autofac, and a number of 3rd party libraries and controls. So not everything else is M$.
I own an NHibernate book http://www.manning.com/kuate/ that is full of good documentation.
There is also online help. www.hibernate.org/.../html/
In addition there is a nhibernate wiki:
http://nhforge.org/wikis/
On top of that there is a user group list on google that is full of quick and good answers to problems:
http://groups.google.com/group/nhusers/topics
There are plenty of tutorials and blog posts to learn the more complex parts of NH as well.
Here is a test... show me an implementation that uses EF that supports hilo where the table has all the ids for all the tables to be used *, and is append only. Find the documentation in EF for this.
It's not about the 'designer' - it's about solving real life problems here - if the most important concern for you to develop your data model is to have a designer, then yes, L2S or EF is easy to do (and so is CodeSmith I'd add).
Of course, I will admit, I don't use the designer for html - I was never a 'frontpage' developer. I took some time, learned html, and never looked back. I'm a fan of asp.net mvc vs. webforms, and find the designer to be rather painful. Then lastly, any xaml work, I prefer intellisense over a designer -the designer never positions things the way I need it to go.
So, I'm not too locked into a 'designer'. But back to the point of the post: I would argue there is plenty of documentation, and to say it's not documented is just not true. Sure, there might be edge cases - but I don't think EF has every edge case documented as well (ie. my example above)
For point 2 (EF is from Microsoft), if you want a counter-argument you could try to get NH accepted into the Codeplex Foundation. I think it qualifies from what I understand. That's the closest you'll get to being 'from' Microsoft, it's like an endorsement.
The fact, that EF is from Microsoft and NH is not means to me, that with NH I have some hope to get some lacking feature I require, with EF I only get "how many employees does it take for MS to replace a lightbulb" speach.
Steve Gentile: I agree, lots of places you can go. Tutorials, blogs, forums. To me, that's just proved my point. Every element of NH support is by developers who do it because they want to. Microsoft pay people to do it.
I'm using NH, and I don't think EF is up to scratch, so I don't have any anti-NH axe to grind - if anything I'm the one keeping NH alive in my company.... but I contend that finding anything out about it for a casual developer is just too darned hard. I'm not a casual developer, I understand bits of NH quite well now, but I still find it difficult to find the right article at the right time (e.g. I still can't get something simple like the HQL elements function to work. I think the documentation is out of date, but I'm not sure and I haven't been able to find a simple article amonst the multitude of blog entires that explains it properly)
NC: I don't use blend but we have a graphic designer in our company who hates it. he wants to be given a programmer generated design that he can make look beautiful. He says he still needs to delve into XAML and still can't make it do things he wants. He prefers Flash and the Adobe set by a mile.
Sorry, should have said "current support" is by developers who do it because they want to (and means if they don't want to, there is no support... same issue with all OSS).
The book is out of date for the current NH version.
@Graham, the last company i worked for, the designer didn't need to know XAML. The design was done in photoshop, cutup and put into blend, given to the programmer, and the programmer made minor changes to the xaml to include the bindings they had done.
Altho the designer hated blend, they had no issues getting it to do the things they wanted.
I used to be a flash developer, and any designer who perfers flash over silverlight/wpf, can't program AS3, and doesn't know the pains of programming in AS3.
Being able to write C# and do all the things i used to do in flash, in silverlight/wpf, is a godsend.
I am not familiar with NHibernate very much but as far as I know neither HQL not Criteria API provides type safe querying. The only option is Linq provider which is new and not very mature.
In my opinion if an ORM should have at least one strongly typed querying option except Linq.
I have not spent much time with either EF or NH but based on the little time I have spent with NH, I understand that there is no property level dirty tracking feature built in. Nhibernate depends on copying the retrieved object and comparing it upon save to determine what needs to be persisted.
I believe that NH has extension points where you could implement your own change tracking mechanism, but I don't think there is an out of the box solution.
I'm not attempting to argue that one approach is better than the other, just that I think it is one thing that EF can do that NH does not.
@John We use NHibernate Lambda Extensions for that
Ayende,
I think you may be looking at this in the wrong way. The question shouldn't be "what can EF do that NH can't", it should be "what can NH do that EF can't". Like it or not, EF is going to be the default choice for many .NET shops simply because it comes from Microsoft. Because of that, the onus is on NH to prove that it can do things that EF can't.
The foreign key support in EF may be something that NH cannot do. I am not an NH expert, however, so it may be that NH supports this feature.
Julia Lerman has a post showing how the foreign key relationships can be used.
thedatafarm.com/.../ef4-syncing-foreign-keys-an...
Though it has many uses, here is why I'm excited about this feature. Suppose we have an Order table, and an OrderStatus table. If I want to change the status of an order:
order.Status = OrderStatus.GetByName("Complete");
I may have to query the database in order to hydrate/materialize some object that represents the "Complete" status, just so I can change an Order record. But what if I already know all the OrderStatus values?
enum OrderStatusValues
{
Complete = 1,
Incomplete = 2,
Canceled = 3
}
EFv4 (I hate that it's called v4 by the way, it's v2) will allow us to:
order.StatusID = (int)OrderStatusValues.Complete;
Obviously it doesn't have to be an int, it can be a string, a guid, or any other value that can be a FK, and it is directly assignable. This doesn't require me to do an extra database query. Also, as shown in Julia Lerman's post, assigning FK values directly in this way does not cause any data synchronization issues. If you set order.StatusID directly, then order.Status will reflect the correct OrderStatus object, and vice versa.
Granted, with EF, the reason this FK feature is useful is because EF does not allow you to map to enums, and NH does, which does away with the need _in this example_. There are other good uses of the FK feature, however, so the NH mapping to enums feature does not totally invalidate the FK feature for EF.
As always, excellent food for thought Ayende, keep it up.
Sam,
That is because NHibernate has a better feature.
order.Status = session.LoadOrderStatus; // will NOT generate a DB query.
You get the same benefit, but don't have to deal with FK on your model
Excellent, I didn't know about the differences between ISession.Get <t(id) and ISession.Load <t(id). Nice to know that Load <t(id) returns a proxy, and that nothing will be lazy loaded unless the other properties are used. Indeed, that is a better feature than having to worry about the FK in your model.
I have another feature that perhaps is present in EF that NH lacks, regarding eager fetching. Imagine I have the following tables and relationships:
User <1--> Role <1--> Role_x_Permission <*--1> Permission
(The Role_x_Permission table is to avoid a many-to-many between Roles and Permissions)
In my model, I would want to define the following collections:
User.Roles (What roles does a user have)
User.Permissions (What permissions does a user have)
Role.Users (What users have this role)
Role.Permissions (What permissions does this role have)
Permission.Users (What users have this permission)
Permission.Roles (What roles have this permission)
With EF, I could do something along the lines of:
var q = from user in context.User
.Include("Roles")
.Include("Roles.Users")
.Include("Roles.Permissions")
.Include("Permissions")
.Include("Permissions.Users")
.Include("Permissions.Roles")
select user;
And the entire object graph would be appropriately constructed. It may or may not accomplish this in a single query, but it would be the minimum number of queries possible, and you'd get the correct object graph back, with all of the collections populated with the correct related entities.
With NH, if I do this:
ICriteria crit = sess.CreateCriteria <user()
.Add(Restrictions.Eq("ID", userID))
.SetFetchMode("Roles", FetchMode.Eager)
.SetFetchMode("Roles.Users", FetchMode.Eager)
.SetFetchMode("Roles.Permissions", FetchMode.Eager)
.SetFetchMode("Permissions", FetchMode.Eager)
.SetFetchMode("Permissions.Roles", FetchMode.Eager)
.SetFetchMode("Permissions.Users", FetchMode.Eager);
Then NH will create a number of cartesian product queries, and I will end up with millions of objects in my collections, that are not the proper related records.
Borrowing an answer from a StackOverflow question ( stackoverflow.com/.../eager-loading-of-lazy-loa...>), a user says that:
From "NHibernate in Action", page 225:
Perhaps NH is no longer limited to just one eagerly fetched collection? Perhaps it is? At any rate, I tried the above code with NH, and I got some ugly cartesian products. I do the same thing with my EF code, and everything is correctly materialized.
Thoughts?
Note: In my above comment, the CreateCriteria() call got html-ized, and the generic parameter doesn't show up. It should be
CreateCriteria < User > ()
Sam,
You should be using FetchMode.Join and FetchMode.SubSelect (whichever is more appropriate) instead of FetchMode.Eager.
Sam,
The FetchMode.Eager is alias to FetchMode.Join
You need to either set FetchMode.Subselect for some, or use future queries to load each item independently.
Ayende, excellent! I like to have methods like the following:
IList <t GetPage <t(int pageIndex, int pageSize, params string[] eagerFetches)
So that I can grab any page of data, from any of my entity classes, eagerly fetching any of the related entities. I was trying to accomplish this today, with FetchMode.Eager, and was getting the cartesian product mess. I'll play around with FetchMode.Subselect and future queries tomorrow. Do you have an example of how those might work with my above scenario?
As for features EF has that NH doesn't, I've put my two forward, and you've demonstrated that NH has equivalents. Still, it's a hard question to ask. EF and NH, while both attempt to solve the "impedence mismatch" between the Relational and Object-Oriented worlds, go about it differently. Some features will not be comparable. That being said, I am still on the fence, but am leaning more towards NH. I create a SessionFactory ONCE, so creating a Session for a single user's request/response cycle is cheap and fast. With EF, I have to spin up a new DataContext for each user's request/response, and it takes longer. Everyone is trying to benchmark different OR/M's, and they are benchmarking the wrong things! Who has a site that does millions of CRUD operations? Do you write 10,000 blog posts per second? No, nobody does. I have an ErrorLogger library, with both an NH and an EF version. Looking at logs in a paged GridView takes twice as long in the EF version, because of the time it takes to spin up the DataContext for each postback. I was so excited when I finally got the EF version completed and deployed, to see that it's twice as slow to browse my data. Bummer.
My $0.02.
Your blog steals angle brackets!
IList < T > GetPage < T > (int pageIndex, int pageSize, params string[] eagerFetches)
@Ayende - Are you sure the latest release of NH works in medium trust OOTB???
I had to build with the latest Castle DynamicProxy bits and disable reflection optimization in the app configuration to get it to work.
I am a big NHibernate fan so my opinion is biased. Ironically the best feature NHibernate had over EF was the profiler. I used Nhibernate at my last job and it become orders of magnitude easier to pick up and use once we bought the profiler tool. At my current job we are using EF4 and recently got a copy of the beta profiler and once again I wouldn't use an Orm like NHibernate or EF without out this tool. The EF framework was already built by the time I got on board my current project so I don't know what EF has over NHibernate.
The designer for EF is nice but very slow. I hope NHibernate has a good designer soon simply so it will get more market share. Is EF versus NHibernate going to be Enterprise logging versus log4net? I think that's what is frustrating about EF. Microsoft provided a half baked solution to an already solved problem. Microsoft is known for putting a lot of inefficiency on it's developers.
@Ayende,
I'm not having a lot of luck with Future and FetchMode.Subselect. It seems that FetchMode.Subselect can only be specified in the mapping file, and not with ICriteria.SetFetchMode(). The NHibernate.FetchMode enum does not have a Subselect field. Future is indeed a useful tool, but I can't figure out how to get a connected object graph, so that all of the entities that come back are in their proper parent/child containers, representing how they are related in the database. I may be able to produce separate lists that contain the related entities, but I want an object graph, because that's why I have a model in the first place.
What I like about the EF Include() feature, is that I can specify any number of association paths (as strings) from the root entity type I am selecting, and EF will correctly construct my entire object graph. Again, from my earlier example:
var q = from user in context.User
.Include("Roles")
.Include("Roles.Users")
.Include("Roles.Permissions")
.Include("Permissions")
.Include("Permissions.Users")
.Include("Permissions.Roles")
select user;
I can't find a way to do this in NH without having to issue separate queries, or without producing a cartesian nightmare. When including association paths, I don't have to do something different for collections versus single entities, because Include() works the same for both.
I will keep looking into how to do this with NH, but some help would be fantastic. Also, I'll set up a SQL Server trace, and do my above Include() example in EF, to see how many queries are issued, and what they look like.
Ok, I set up an EF model against some tables, and used a bunch of .Include() calls on a single query. It's interesting that you can go any number of degrees down the "association chain", like this:
.Include("Children.SomeProperty.SomeCollection.SomeCollection.SomeProperty"), etc
And with multiple Include() calls chained, you can take different paths, as in:
.Include("Children.SomeProperty").Include("OtherChildCollection")
I tried half a dozen complex combinations, branching off in 3 directions from my root entity, including all sorts of single properties and child collections in every direction. Every time, EF issued a single query to the database. Not multiple queries in 1 trip, but a single query. Lots of interesting subselects, joins, and unions, but still, impressive. I don't think this is something NH is capable of.
I don't think NH has an equivalent of ObjectQuery<T>Include(string associationPath). Or at least, I've not yet been able to figure out how to accomplish the same thing using Future queries or ICriteria.SetFetchMode().
As I mentioned earlier, the ease of use of Include() allows me to create methods on my entity classes like this:
GetPage(int pageIndex, int pageSize, string where, params string[] includes)
This allows me to get very specific results, with all of the related data I want already eagerly fetched. And it won't matter if the related entities I'm eagerly loading are child collections, individual properties, etc. EF will sort it out, and give me back my object graph.
funny, I've been in the previous article and I'm going to read this one, but 2 things amazed me:
ppl telling "why" and "what" in their arguments and in the same time having just very minor experience/ideas of particular framework, be it NH (too much XML? fluent any1?) or EF (can't POCO via designer etc)
that nobody mentioned, that with a little work, I'm able to setup MONO project using Nhibernate, and that I'm fine with .NET 3.5 requirements (using LINQ)!
EF requires not only expensive MS OS server licences, but also .NET 4.0 is the minimum version it will run on! It may win, but not anytime soon.
I don't know like you, but where I am there are many customers/companies still using .net 2.0 and .net 3.5 is just now taking preferance (mainly due to MVC, it wasn't like that before)...
If I would need a designer, I would go with Lightspeed, from migrations to 10times better desinger than EF with full LINQ provider and commercial support...
IF I would need a designer...
Long Live NHibernate! <3 EF just plain sucks... worst ORM EVER. Maybe I'll reserve the worst for Telerik's OpenAccess. =/
I would like to suggest that anyone that says "EF is from Microsoft." has never been burned by a Microsoft technology. It does happen. If you haven't experienced it, then you probably will at some point. When it does, you have to be honest with yourself when asking "Did I do the right thing or was I naive by accepting what Microsoft offers?"
Until you get burned by MS, you will, IMHO, usually accept whatever it is they put out. But once you get burned, it's a bitter-sweet moment. One where you are upset you didn't see what was happening, but sweetened by the fact that you are free do do what you like, unencumbered by the MS marketing machine.
Think for yourself and resist the temptation to be spoon-fed.
@Ivos
"There’s not NH vs EF. There’s NH for those that work as community does and EF for the ones that goes to church every sunday morning. "
I had sucha good laugh reading this. Nice one Ivos.
Behind its sarcasm I believe that the phrase speaks the truth, that is, NH it's more likely to be appreciated by people trying to live in the OO world & paradigms as NH is conceptuall designed arround those concepts, while EF and Linq to SQL comceptually start their mission from the DB perspective.
Regarding documentation, it definitelly takes more work and time to find how to work with some NH features than probably anything comming from MS, but on the other side when the primary documentation is about how to click in the IDE to get some technology working it suddenly makes that technology so unapealling (for me at least and I liked EF so much initially when I read about what it should be).
Anyway, great job Ayende, I just don't understand when you find time to do it...
Comment preview