In honor of the (relatively) new 1.0 status of LINQ to NHibernate, I’ve been spending the last few nights LINQifying some old NHibernate queries I’ve written and I must say that I’ve been very pleased.
There have traditionally been two ways of specifying NHibernate queries: HQL and the criteria query API.
Although I have an easier time deciphering HQL, which is basically a SQL-like string using classes instead of tables, I’ve tended to use the criteria API because it was somewhat strongly typed and thus easier to maintain with the help of refactoring tools like ReSharper.
Thanks to the new NHibernate LINQ provider, I can now work in a mode that is not only more type safe, but also much more readable.
Look at these before and after queries and judge for yourself:
Before (Criterion API)
1: public IList<Call> GetCallsByDate(DateTime beginDate, int interpreterId)
2: {
3: ICriteria criteria = Session.CreateCriteria(typeof(Call))
4: .CreateAlias("Customer", "Customer")
5: .Add(Restrictions.Gt("StartTime", beginDate))
6: .Add(
7: Restrictions.Or(
8: Restrictions.Lt("EndTime", DateTime.Now), Restrictions.IsNull("EndTime")
9: )
10: )
11: .Add(Restrictions.Eq("Interpreter.Id", interpreterId))
12: .AddOrder(Order.Desc("StartTime"))
13: .AddOrder(Order.Desc("Customer.Name"));
14:
15: return criteria.List<Call>() as List<Call>;
16: }
After (LINQ to NHibernate)
1: public IList<Call> GetCallsByDateWithLinq(DateTime beginDate, int interpreterId)
2: {
3: var query = from call in Session.Linq<Call>()
4: where call.StartTime > beginDate
5: && (call.EndTime == null || call.EndTime < DateTime.Now )
6: && call.Interpreter.Id == interpreterId
7: orderby call.StartTime descending, call.Customer.Name
8: select call;
9:
10: return query.ToList();
11: }
Apparently the NHibernate guys are still working on a full featured LINQ provider for a future version of NHibernate, but decided that the LINQ provider in the contrib project has been tested enough and used in enough production systems to promote it to RTM status.
The one thing I did notice when peeking at the SQL in Profiler is that the Linq provider produced an extra join that the regular Criteria API figured out wasn’t necessary because I was just referencing the foreign key column in the where clause. I’m guessing that minor differences like this will be addressed in the next version of the provider.
In the meantime, I’m still hooked enough to want to use this approach instead.
If you want to give LINQ to NHibernate a test run, just download and reference the one required dll here (make sure you’re using the same version of NHibernate).
If you’re still not comfortable with LINQ sytnax, here’s a simple example based MSDN tutorial to get you started.
Popularity: 30% [?]






Jan: Blogging Without a Net – I started off the year with a resolution to