In some cases, it may be preferable to build an HQL or criteria query object in parts of your application without access to the NHibernate session, and then execute them elsewhere with a session. In this recipe, I'll show you how to use detached queries and criteria.
Set up a new NHibernate console application using our Eg.Core
model from Chapter 1. Configure log4net to send the NHibernate.SQL debug output to the .NET trace, just as we did in Chapter 2.
Add the following code to your Main
method:
var isbn = "3043"; var query = DetachedCriteria.For<Book>() .Add(Restrictions.Eq("ISBN", isbn)); using (var session = sessionFactory.OpenSession()) { using (var tx = session.BeginTransaction()) { var book = query.GetExecutableCriteria(session) .UniqueResult<Book>(); tx.Commit(); } }
In this recipe, we've used a DetachedCriteria
object from the NHibernate.Criterion
namespace. This allows us to set up our query without an active session. Later, inside a transaction, we call GetExecutableCriteria
to return an ICriteria
associated with the session. Finally, we call UniqueResult
to return the book.
NHibernate also provides DetachedQuery
and DetachedNamedQuery
in the NHibernate.Impl
namespace for detached HQL queries. The code is given as follows:
var query = new DetachedNamedQuery("GetBookByISBN") .SetString("isbn", isbn); var query = new DetachedQuery(hql) .SetString("isbn", isbn);
Detached criteria and queries implement the query objects pattern shown on Martin Fowler's website at http://martinfowler.com/eaaCatalog/queryObject.html.