Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 5,953 | Comments: 44,399

filter by tags archive

Implementing Linq for NHibernate: A How To Guide - Part 1

There is an appaling lack of documentation about how to implement Linq providers. The best resource that I could find is Fabrice's post about Linq To Amazon. The Linq In Action may provide additional information, but from what I have seen it is about using linq, not build a provider yourself. Since I would really like people to pitch in and help with the implementation of Linq for NHibernate (not that this is a hint or anything), I decided to document what I found out while building Linq for NHibernate.

I strongly suggest that you would get the VPC Image and use that to explore what is possible. The code, to remind you, is at:

svn co https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/experiments/NHibernate.Linq/

My goal at the moment is feature parity with the 101 examples that Microsoft have published.

I am not going to explain in detail how Linq works, you can go to other sites to find that out, but here is a short introduction. Linq is an extention to the compiler that turns certain keywords into method calls. The interesting part it that the compiler can give you the AST (Abstract Syntax Tree) for the query instead of executable code. This is important, because then you are free to take actions based on the AST (for instance, make a database call).

The whole concept revolves around two main ideas, IQueryable<T> and Expression which are tightly linked together. The compiler will output an Expression tree that will be passed to the IQueryable<T> implementation. Of course, there need to be an IQueryable<T> implementation, and that is where extention methods come into place. I implemented to core functionalty by adding an extention method to ISession, like this:

public static class LinqForNHibernate


    public static IQueryable<T> Linq<T>(this ISession session)


        return new NHibernateLinqQuery<T>(session);



Now I can execute this query, and NHiberanteLinqQuery get to intercept the expression tree:

var query = (from user in session.Linq<User>() select user).ToList();

The rest of this post is going to focus mostly on the NHibernateLinqQuery implementation. I have choosen to base the Linq implementation on the criteria API. This make the task a lot simpler, since I can let mature API handle a lot of the underlying query generation. The criteria API does not exposes 100% of the functionality offered by NHibernate, but it offers most of it, and saves me the need to handle query generation myself. Where I would need features in the criteria API that do not currently exists, I can add them.

Here are the fields on NHibernateLinqQuery:

ISession session;

ICriteria rootCriteria;

IDictionary<ExpressionType, Action<System.Linq.Expressions.Expression>> actions;

Stack<IList<NHibernate.Expression.ICriterion>> criterionStack = new Stack<IList<NHibernate.Expression.ICriterion>>();

IList<TResult> result;

The session and rootCriteria are probably obvious, but actions require an explanation. Each Expression has an ExpressionType, and the action dictionary contains the matching methods that can handle them. Basically, each ExpressionType is handled by a method Process[ExpressionType] on the NHibernateLinqQuery. Here is an example of the method that handles ExpressionType.Lambda:

public void ProcessLambda(Expression expr)


    LambdaExpression lambda = (LambdaExpression)expr;



Where ProcessExpression is implemented as:

public void ProcessExpression(Expression expr)




Basically a visitor pattern with the actions dictionary serving as the dispatcher.

The criterionStack contains all the current predicates about the query. It is a stack of a list of ICriterion, and the idea is that I can insert a new list to the stack, have it process some of the expression, and then pop the list and use the processed items. Let us see this in code, we have the CurrentCritetions, which all the Process[ExpressionType] will handle, which is simply:

public IList<NHibernate.Expression.ICriterion> CurrentCriterions


       get { return criterionStack.Peek(); }


Once we have both of those, we can then use it for complex expression, like handling [user.Name == "ayende" || user.Name = "rahien"]:

public void ProcessOrElse(Expression expr)


       BinaryExpression and = (BinaryExpression) expr;

       criterionStack.Push(new List<NHibernate.Expression.ICriterion>());



       IList<NHibernate.Expression.ICriterion> ors = criterionStack.Pop();


       NHibernate.Expression.Disjunction disjunction = new NHibernate.Expression.Disjunction();

       foreach (var crit in ors)






We push a new list to the stack, process the right and left expressions of the or, pop the current critetion list, and then we combine them into a disjunction, which we push into the original criterion list. This way we don't have to worry about complex expression, they are mostly handled by themselves.

Now that I talked about how I am parsing the expression tree, let us talk about how the query is handled. Again, this isn't documented that I have seen, so I am mainly talking about what I discovered. The first thing that happens is that the IQueryable<T>.Expression property is called. Basically it is asked to give what sort of an expression should handle this query. I choose to handle the query in the same IQueryable<T> implementation, so I am returning this reference:

public System.Linq.Expressions.Expression Expression


       get { return System.Linq.Expressions.Expression.Constant(this); }


Then, the CreateQuery<TElement> method is called. it is important to understand the difference in the <T>'s here. The query itself is a generic type, NHibernateLinqQuery<TResult>, where TResult is the entity that we are querying. The result of the query may be different than TResult, because we may use projection to get only some of the values, or select a child item values.

Therefor, we need to return a new IQueryable<TElement>, which is why I am creating a new instance of the same class, passing it the current state of the objects, and continue to parse the expression tree.

As you can see, I am only handling the Select and Where methods at the moment. My naming convention at the moment is "HandleXyzCall" is to handle a query method, while "ProcessXyz" it to process an expression type.

public IQueryable<TElement> CreateQuery<TElement>(System.Linq.Expressions.Expression expression)


       MethodCallExpression call = (MethodCallExpression) expression;

       switch (call.Method.Name)


              case "Where":



              case "Select":





       foreach (var crit in CurrentCriterions)




       return new NHibernateLinqQuery<TElement>(session, rootCriteria);


The HandleWhereCall is very simplistic, it just process all the arguments passed to the where clause:

private void HandleWhereCall(MethodCallExpression call)


       foreach (Expression expr in call.Arguments)





The select method is a bit more complex, since it need to handle projections and other various interesting features. I am not going to show it here, because it is over 50 lines of codes and it is very state machine like. Not really interesting.



Looks like there are others trying to create open source linq providers as well...


Ayende @ Rahien

Linq for NHibernate Updates: Adding a new committer

Roger Jennings

Pingback from http://oakleafblog.blogspot.com/2007/03/third-party-linq-providers.html

Wooley's Wonderings

It was only a matter of time before more people started work on extending the LINQ structure to other...

Mike Taulty's Blog

This series of posts&nbsp;is going to be interesting whether you use NHibernate or not as it starts to...

ScottGu's Blog

Last month I started a series of posts covering some of the new VB and C# language features that are

Linq in Action News

In the spirit of LINQ to Amazon now comes LINQ to Flickr . Mohammed Hossam El-Din ( Bashmohandes ) proposes




Whats the point? we can bypass hiberanate and go straigt to the store can we not. Screw hibernate.

Ayende Rahien


Please moderate your language.

The point is getting the nice Linq syntax with all the power in NHibernate.

Eugene Tolmachev

Great stuff,

Combining LINQ with the power of NHibernate should be awsome. Especially considering MS is dropping the LINQ to Entities from Orcas...

Comment preview

Comments have been closed on this topic.


  1. Comparing developers - 38 minutes from now

There are posts all the way to Jun 30, 2015


  1. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
  2. Special Offer (2):
    27 May 2015 - 29% discount for all our products
  3. RavenDB Sharding (3):
    22 May 2015 - Adding a new shard to an existing cluster, splitting the shard
  4. Challenge (45):
    28 Apr 2015 - What is the meaning of this change?
  5. Interview question (2):
    30 Mar 2015 - fix the index
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats