Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,640
|
Comments: 51,263
Privacy Policy · Terms
filter by tags archive
time to read 1 min | 92 words

Following several good patches, I have added Bobby Diaz to the Rhino Tools project, which currently includes the Linq for NHibernate implementation as well. I expect that the new stuff will be up in the repository shortly.

Just to remind you, I am still looking for more volunteers to help with the implementation, so if you are into futuristic technologies, just dive right into the code and the implementation details. And be sure to send me (or Bobby) a patch or two.

time to read 1 min | 170 words

Bobby Diaz has implemented orderring and paging support for Linq to NHibernate, so this works:

(from c in nwnd.Customers select c.CustomerID)
        .Skip(10).Take(10).ToList();

As well as this:

var query = from c in nwnd.Customers
   where c.Country == "Belgium"
   orderby c.Country descending, c.City descending
   select c.City;

Thanks again, Bobby, and the new code is on SVN.

time to read 3 min | 407 words

Jeremy has a great post summarizing the MVP summit, and he include:

Linq for Entities is much more than an O/R Mapper.  It potentially provides us with a unified data access strategy over heterogeneous data sources (web services, xml, non relational databases, etc). 
  • Web service call is (a remote remote call - extranet/internet)
  • Non relational databases
  • Hierarchical data stores
  • Relational databases

Now consider the following query:

Customer customer = (from c in someHeterogeneousDataSource.Customers
   where c.Name == "Ayende" select c).First();
  • If the web service expose a GetCustomerByName(), this would be a good candidate, if not, the implementation would need to call GetAllCusomters() and filter it in memory.
  • For non relational databases, I am aware of object databases, flat files, temporal and hierarchical (covered seperatedly) - each of which has its own tradeoffs. I am not familiar with object databases to say what the tradeoffs are here, but for a flat file, it is going to be a linear scan. The query is not even a valid one for a temporal database (unless there is an implict CurrentTime).
  • For hierarchical data stores, this query would need to iterate all the customers, and compare their name to the query.
  • Relational database would think that this is too easy, and quit.

And this is just about the simplest query possible. I can't guess what will happen if I happened to want a join between customer and orders.

I get the feeling that I am missing something here, because it sure isn't heterogeneous to me.

time to read 1 min | 198 words

I got a couple of great patches yesterday and today, Bobby Diaz sent a patch to add support for Count() and DataContext like behavior. Jon Stelly went and cleaned up my code, turning it from a sleep-deprived hack into a respectable project. You can see his full list here. Thanks to their efforts, this now works:

(from user in orm.Users select user).Count();

I changed the implementation of NHibernteLinqQuery to use the visitor pattern, which is the natural way that I think about walking through an AST. It is still very primitive one, but it does the job that we need right now.

The new code is in the repository:

Bobby and Jon, thanks again. Everyone else, you are invited to the party as well.

time to read 22 min | 4320 words

Jeff Brown commented on my Linq Options post:

Pity they didn't shoot for lexically-scoped blocks a la SmallTalk (or Ruby)...  This approach with Expressions has the same control-flow limitations as anonymous delegates but you can omit the curly braces sometimes.

Linq is not just anonymous delegates. (I should be clear that I am mostly thinking about the abilities of Expression rather than the Langague Integrated Query here). It means that I can start doing some really stuff. For what it worth, there is such a thing as the ExecutionScope for linq, but I am not sure what it is supposed to do, as far as I can see, it is the entire lexical scope for the expression.

Here is a trivial example that shows what you can do with it. Assume that I have this work item (and saved action):

[Serializable]
public class WorkItem

{

    string name;

    string action;

    string on;

 

    public WorkItem(string name, string action, string on)

    {

        this.name = name;

        this.action = action;

        this.on = on;

    }

    public WorkItem() {}

 

    public void DoAction()

    {

        Console.WriteLine(name +" "+action+" " +on);

    }

}

 

[Serializable]
private class SavedAction
{
   public object target;
   public string method;
}

And I have this code:

public delegate void Act();

static void Main(string[] args)
{
    WorkItem wi = new WorkItem("Ayende,", "write", "blog post");
    Save("Temp.action",() => wi.DoAction());
    Act act = Load("Temp.action");
    act();
}

What is going on here? I am saving the labmda into a file in the Save(), then load and execute it in the next two statement. Sadly, Linq's Expression<T> are not serializable, which I consider a huge minus, but for this example, I worked around it a bit. Here is the code for the Load, which isn't really interesting:

private static Act Load(string file)
{
    SavedAction action;
    BinaryFormatter bf = new BinaryFormatter();
    using (Stream s = File.OpenRead(file))
        action = (SavedAction)bf.Deserialize(s);
    return (Act)Delegate.CreateDelegate(typeof(Act), action.target,
        action.target.GetType().GetMethod(action.method));
}

The Save() is where the real magic begins, I compile the expression, extract the target, extract the method that was about to call, and save it, for later processing in the load.

private static void Save(Expression<Act> actionToSave)
{
    Act act = actionToSave.Compile();
    ExecutionScope scope = (ExecutionScope)act.Target;
    SavedAction action = new SavedAction();
    MethodCallExpression l = (MethodCallExpression)actionToSave.Body;
    action.target = Expression.Lambda(l.Object).Compile().DynamicInvoke();
    action.method = l.Method.Name;
    BinaryFormatter bf = new BinaryFormatter();
    using(Stream s = File.Create("Temp.action")) 
        bf.Serialize(s, action);
}

I am very excited about these capabilities. Yes, I can do it today, but the inteface I would have to expose is wholly unatural, while Linq provide for much nicer alternative.

time to read 26 min | 5065 words

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;

    ProcessExpression(lambda.Body);

}

Where ProcessExpression is implemented as:

public void ProcessExpression(Expression expr)

{

    actions[expr.NodeType](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>());

       ProcessExpression(and.Left);

       ProcessExpression(and.Right);

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

 

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

       foreach (var crit in ors)

       {

              disjunction.Add(crit);

       }

       CurrentCriterions.Add(disjunction);

}

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":

                     HandleWhereCall(call);

                     break;

              case "Select":

                     HandleSelectCall(call);

                     break;

       }

 

       foreach (var crit in CurrentCriterions)

       {

              rootCriteria.Add(crit);

       }

       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)

       {

              ProcessExpression(expr);

       }

}

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.

time to read 4 min | 709 words

The code that I am going to show is working code. I have it passing tests on the March 2007 CTP, against NHibernate 1.2 CR1.

Select entity and filter:

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

Project a property:

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

Project anonymous type:

var query = (
        
from user in session.Linq<User>()
         
select new { user.Name, user.RegisteredAt }
     ).ToList();

Where do you get that?

You can get the source from Subversion:

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

You can also download it from the download page.

Caveats:

  • It is by no means a complete Linq implementation. The 101 examples for Linq are a good test metric to go against, in my opinion, and I am only hitting 13 of them right now (probably more, but I have tests for 13).
  • I read the C# 3.0 spec when it was out in PDC '06, and last night I got the March CTP and started working on an implementation. This is literally my baby steps with Linq.
  • I am not going to invest a lot of time in this. It is still far into the future, and I mostly did it to make people stop wishing for it.

Important - patches:

I would appriciate it if you will send bug reports with patches to fix them.

Have fun, and don't make too much out of it.

time to read 2 min | 266 words

As usual, just a set of random impressions:

  • Anonymous types are annoyingly limited. You can't define arrays of anonymous types, for instnace, which can open up more options for intent revealing code.
  • Linq seems to be heavily based around the idea of Expression, a lot of the stuff that is going on there revolves around Expression and operation on Expressions.
  • Here is a new way to assert that a collection contains all the items that it should:
    Assert.AreEqual(3, list.Intersect(new string[]{"ayende","rahien","bar"}).ToList().Count);
  • I am annoyed that this doesn't work, though:
    Assert.AreEqual(3, list.Intersect({"ayende","rahien","bar"}).ToList().Count);
    Shouldn't this be handled by the collection initializer?

 

time to read 1 min | 106 words

Insomniac dreams. I am awake since about 2:30 AM (it is 07:30AM now), which meant that I had a chance to read my feeds, catch on my emails, do some OSS work, release a new beta and post too much :-). Just thought that I should explain why you see so many posts all of a sudden.

Anyway, the reason for this post is asking how the ADO.Net Entity Framework will handle dynamic queries. I am talking about something like this example. I just read John's post about the Entity Framework, and the question just came up in my mind.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. API Design (10):
    29 Jan 2026 - Don't try to guess
  2. Recording (20):
    05 Dec 2025 - Build AI that understands your business
  3. Webinar (8):
    16 Sep 2025 - Building AI Agents in RavenDB
  4. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  5. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
View all series

Syndication

Main feed ... ...
Comments feed   ... ...