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 co...

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: 22 Jul, 2008 07:38 PM History

Comments

02 Aug, 2008 04:58 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);

06 Aug, 2008 10:57 AM

Yes, this makes much more sense to me. Thanks for the suggestion :)

23 Jul, 2008 01:46 AM

VERY CLEVER!

I love wins like this....

Thanks!

Damon

04 Nov, 2008 03:12 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.