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.
.NET Code Snippets NHibernate
Posted by: Brendan Kowitz
Last revised: 21 Sep 2013 12:15PM

Comments

7/23/2008 1:46:59 AM
VERY CLEVER!

I love wins like this....

Thanks!

Damon

8/2/2008 4:58:38 AM
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);
8/6/2008 10:57:20 AM
Yes, this makes much more sense to me. Thanks for the suggestion :)
11/4/2008 3:12:27 PM
I've been using strongly typed criteria too for some months now, it works great. Take a look at my implementation: bugsquash.blogspot.com/.../...e-criteria-with.html

No new comments are allowed on this post.