NHibernate Type Safety using Lambda Expressions

I can't remember if this has been around before, I do vaguely remember seeing something like it.

However, I just wanted to apply a snippet of code I found on Paul's blog the other day to NHibernate. Of course we will definitely have type safety in queries when Linq-to-NHibernate is completed. But surely linq-to-nhibernate is not going to be the _only_ way of writing queries.

Using the original code snippet 'as is' would look something like this:

ICriteria c = session.CreateCriteria(typeof(Person));
c.Add(Restrictions.Eq(Property.GetFor(() => new Person().FirstName), "John"));

This is ok, but a little long winded, so I implemented another class called RestrictBy which can break down a simple lambda expression. So now I can use:

ICriteria c = session.CreateCriteria(typeof(Person));
c.Add(RestrictBy.Eq(() => new Person().FirstName == "John"));
c.UniqueResult();

This also means you'll get compile time errors for incompatible types such as:

Lamba expression error

Using the lambda expression we get to evaluate the _actual_ property and that property's type. If you wanted to clean this up some more, its not hard to then go and add some extension methods to ICriteria to produce:

ICriteria c = session.CreateCriteria(typeof(Person));
c.AddEq(() => new Person().FirstName == "John");
c.UniqueResult();

So that's it, a simple example at the moment, but it might be an option to look into a little more because the ICriteria interface is still NHibernate's native querying interface and still provides a lot of power, flexibility and programmatic building of queries.

Sourcecode:

EDIT: For further reading, see the follow up post.

Print | posted on Tuesday, July 22, 2008 7:38 AM

&uot&uot

Comments on this post

# re: NHibernate Type Safety using Lamba Expressions

Requesting Gravatar...
VERY CLEVER!

I love wins like this....

Thanks!

Damon

Left by Damon Wilder Carr on Jul 22, 2008 1:46 PM

# re: NHibernate Type Safety using Lambda Expressions

Requesting Gravatar...
Hi Brendan,

You could probably make an overload for the method that stops you needing to create the new Person() object each time. For example:

Property.For<Person>(p => p.FirstName);

The signature for Property.For would be:

public string For<T>(Expression<Func<T, object>> callback);
Left by Paul Stovell on Aug 01, 2008 4:58 PM

# re: NHibernate Type Safety using Lambda Expressions

Requesting Gravatar...
Yes, this makes much more sense to me. Thanks for the suggestion :)
Left by Brendan on Aug 05, 2008 10:57 PM

Your comment:

 (will show your gravatar)
 
Please add 8 and 5 and type the answer here: