views:

102

answers:

3

I'm trying to evaluate NHibernate.LINQ 1.0 without actually writing any code. Ayende has admitted that this version of LINQ support is subpar compared to EF, but for the life of me I can't seem to find a page that explains what's supported and unsupported in this implementation. For example, can I use Skip & Take? What can I not use?

+3  A: 

The basic test of whether NHibernate can work with a Linq statement is whether you can serialize that statement's expression tree, then deserialize it in a different process and get the right answer. That means no external closures; the lambda must work only with what it creates or is given as a parameter.

Linq2NH 1.0, IIRC, also chokes when using members of the class that are not mapped, so if, for instance, you have a read-only calculated property like a special weighted or rolling average, you must map it to a DB column in order to reference it in the lambda (or recreate the logic in the lambda). This is because the expression tree will eventually be boiled down into SQL (through one of NH's intermediates; in 2.x it's ICriteria, in 3.x it's HQL) and if NH cannot take an expression and convert it 1:1 into a SQL expression that will evaluate successfully, it's just not going to work.

There is one special case: Linq2NH, IIRC, is smart enough to turn an IList.Contains() expression into an IN clause. The list must be defined within the lambda (like new[]{"1","2"}.Contains(m.ID)).

KeithS
Very good answer, just one correction - the way you phrased it in 3.x that it goes via HQL, it sounds like you're saying the LINQ query gets get turned into an HQL string first.What happens is the expression tree gets parsed back into the same AST's that the HQL ANTLR parser targets. This is much more efficient than targeting a string ;)http://blogs.imeta.co.uk/sstrong/archive/2009/02/22/617.aspx
Kevin McKelvin
+3  A: 

The blog post from Ayende is from May this year. A lot of things changed. The NHiberante. Linq 1.0 linq provider is depricated since about a year because of the new linq provider in the NHibernate Trunk. The new linq provider is not completely finished yet, but already very complete and usable for much more than the old linq provider. Things that do not work with the new linq provider are considered bugs and will be solved some day when reported.

You can use skip and take with the old and new linq provider. The current list of known issues can be found on NHiberante Jira. Other issues are unknown and all other features are already supported.

Paco
+4  A: 
Rafael Belliard
Good answer +vote! Note that the NHibernate trunk is stable for all features implemented in the previous release. The issues are some old issues and issues in new features. The linq provider in the trunk is more stable than the other one. A lot of people use the trunk in already running major applications.
Paco
The stable version seems to support all the aggregates. For example I use MAX and it translates all the way through to the DB and gets executed there. Note that there is a little bug with string comparisons if you are using VB.NET. I found that out the hard way. Just use myStr.Equals("foo") rather than mystr = "foo" and it works just fine. Not an issue if using C#.
Bytemaster
@Paco: good to know. I'll try moving one of my apps to NH trunk and see how it works out (in a testing environment, of course).
Rafael Belliard