What is the story behind the Entity Framework vs. NHibernate posts?
A while ago I posted several posts about EF vs. NH. They generated quite a bit of commentary, but while I enjoyed the discussion, I had an ulterior motive for doing so.
I wanted to do this as a way to do a comparative research about the actual features that people would like to see in NHibernate.
Comments
I feel used and, and... and dirty.
;-)
I'm just sorry I couldn't give meaningful contribution to the debate. I've enjoyed following it. It's been fun.
the feature I wanted the most has been implemented recently already, namely lazy loaded properties. Good job on that one :)
I believe it was determined that was biggest feature (besides LINQ) was that EF often uses unions instead of joins during eager loading to prevent loading lots of redundant data in multi-level entity graphs. Is a similar fetch mode going to be available in NHibernate? This would be especially useful when you need to do paging.
actually there are still two more feature I would appreciate a lot, and that is being able to access output parameters and multiple result sets from stored procedures without having to resort to classic ADO.NET...
Pretty clever :)
Hope it works - competition will make both software better.
My vote would be to be able to re-associate dirty objects with a session. That and maybe finding some serious digging into whether a session can be a bit more robust around exception scenarios. (Less need to drop objects and reload in a new session.) Though if option 1 worked, at least then objects from the dead session could be re-attached.
I know I brought this up with you before. Still, for NHibernate or any ORM to work reliably in more stateful environments such as Windows apps, or even new stuff like Silverlight, the ability to reliably re-associate potentially dirty objects with a session (without forcing an update to the DB then and there) would be very useful.
Steve,
NHibernate has good support for that, session.Merge()
PS,
While NH support native SQL, there are some things that we are just going to consider outside our scope.
Stuff like the things you are talking about are such things. They are rare enough that we literally would invest more time in solving them than it would be worth.
Yes, the ability to re-associate dirty objects with a session would be really helpful.
Then, i miss some way to intercept the collection loading process. There are often situations where i don't need the hole object graph of an 1:n association of an entity. Yes i could use Session or Mapping based filters, but thats not always possible when those filters depends on a specific context or situation.
But maybe i just miss something in the current NH implementation.
So what things do you see people want in NHibernate?
Belvasis,
session.CreateFilter() ?
Karsten,
Read the post comments.
Now this feature request will be a bit uninformed because i never tries linq to nhibrenate in depth but it seemed to me that it was much inferior to linq2sql when i comes to query translation. I remember that group joins were not possible a few month ago (i think this is fixed?) and i don't know if i can use (First|Single)(OrDefault)? inside my query for example in a where statement. This is often useful to get the most recent subobject like the latest post in a forum thread. Also set operations are not fully supported. You might consider this out of your scope too (which is a legitimate choice) but I personally do not.
@Ayende
yes I know this, but i don't want to access a session from within my entity. Let's assume an Employee entity has a collection for it's Appointments and a collection for it's WorkingTime. Now i want to calculate the remaining time for new Appointments in a specific date range as part of my business logic. So i don't need data from outside the given date range. And then what happens if i want to do Appointments.Add(new Appointment()) and the collection is not loaded? So i have to put this logic outside the entity what means, i have to refresh the entity afterwards to make the Appointment collection synchronized. But as i mentioned before, maybe i miss something or should think in different directions.
You create two collections, you filter on one, based on the context, and you set the second AllAppointments as a bad with inverse="true", which won't load everything if you add it
Component inheritance mapping +1
Linq + 1
Eager fetching was the biggest thing that came up for me.
The EF api (Include extension method) permits you to safely eager fetch multiple collection associations, with each eager fetch costing only an additional select and thus a predictable performance impact. This seems to be an ideal compromise for most scenarios and certainly the most sensible default. There could be performance issues if the where condition is expensive (e.g. ColumnName LIKE '%123%') as the table scan would be repeated for each association - might be a different strategy for that but I digress...
With NHibernate, the Criteria API (SetFetchMode) seems to offer similar flexibility at face value, but you can't realistically eager fetch multiple collection associations.
That doesn't mean rewriting NH query engine to do unions though - the existing "subselect" fetch mode could be used to provide a quick win. We would need to support the following scenario:
Fetching strategy for the Blog.Posts collection is set to subselect
Collection is marked for eager fetching criteria.SetFetchMode("Posts", FetchMode.Eager)
Subselect should be issued immediately after the select query for the root entity
This would offer equally flexible control over collection fetching and possibly better performance in case of expensive where conditions. It would also resolve the paging issue.
At the moment, if you do this, NH uses an outer join to fetch the collection. I'd have expected that setting FetchMode.Eager would use the fetch defined on the collection in the mapping.
Even though I posted about MultiQuery support for sql-queries. I have to agree with the other posters about eager fetching multiple associations. IMO this should be top priority. This is always a pain point for me and my team (we have a legacy DB that requires many joins :( ).
I would like to ability to assign the result of a query to a property.
So for every entity/class, it would execute a defined query that uses other data in that class and assign the result to the property. Basically:
Class1.Property1 = (select * from table1 where....)
Dan,
That feature exists, it is called a Forumla
Guys,
This isn't the place for feature suggestion.
The right place is http://jira.nhforge.org
Aha...the slow hand penetrates the shield...
what i would like more is something like that:
to have the possibility to map some objects on one db (e.g. a sql server database), some others on another db (e.g. a mysql database) but have the possibility to use them as if they were persisted in one db only (joins, relationships, hql...)
beleive or not i have several use cases where this would be incredibly useful to me
Vigj,
Oh, it is easy, create a db link between them and move on.
The performance would SUCK, but it is possible.
Or look at NHibernate Shards
ah NHibernate Shards...looks like an abandoned project to me...
even the source (e.g. java material) is looking abandoned (by google), beta 3 being the "release" version if I remember correctly
what is the story behind it? some momentum was started there by you couple of months ago, but I've looked on it 2 weeks ago but didn't see any activity on this field...
I understand it's free project, but I would even pay for such a kind of feature... Ayende, start "donating shards" page ;)
cowgaR,
I can't comment on the Hibernate one, but the NHibernate one is functional.
I suspose you're going to build in a VS designer for NHi bernate and then sell NH to MS? :)
The only features I kept hearing about were:
EF is from MS and not open source
EF has a designer and NH doesn't
Throw in the Linq part but I think that is covered
Sorry for my sarcasm in advance. :)
Oren,
I thought Nhibernate is a direct port of Hibernate and all features are directed by Hibernate.
I am all in for Linq 2 NH(since its on top of criteria)..
Personally I think Linq and querying in general is absolutely an issue for newbies and more experienced developers alike. We use NH throughout our project, and writing queries is a pain. Both Query API and HQL are not compile time safe, and as a result our finder/fetch methods are the hardest things to write in our system accurately.
We've started to us the Lamda Extensions in NH - this seems to provide a good work around and is already increasing productivity - however they do feel like a hack to me in the way they work. Perhaps native support for this would be good.
Does anyone know when the new Linq provider will actually come out? Steve Strong keeps alluding to "only a few weeks"....
Quintin,
NHibernate IS a port of Hibernate, but we are not limiting ourselves to what Hibernate supports.
NHibernate has a whole set of features & bug fixes that Hibernate does not support
Oren,
Unrelated but, why is implementing L2NH (apart from the basic features in 1.0) taking so much time? Is it too complicated a task implementing a Linq provider (esp. since e EF supports it with a lot of advanced options)?
Quintin,
Supporting a basic Linq provider is hard, but doable.
Supporting an advanced Linq provider is three orders of magnitude harder.
No I was asking for what you concluded. Since this was your intend with the post, why not share it?
Karsten,
See the commit log :-)
My vote is similar to one above, make the session more stable so that if it fails for an non-critical DB issue (timeout, connection lost) that won't have impacted data anyway, you can just retry the Flush/Commit without having to dump the session and reload everything.
Really annoying (as it's best practice to retry AFAIK) and never understood why tbh
Comment preview