Coding out of procrastination

A developer’s rants and light bulb moments!

NHibernate & Linq – Free yourself from NHibernate

without comments

Note: This is tested against 2.0 not the 2.1 Beta. Today I’ve been experimenting with NHibernate.Linq against the GA release, there are apparently a few issues and a new version under development which takes a different approach rather than parsing to the criteria API, but hopefully the public API should be the similar whatever version gets released.

In the past I’ve hated leaking ICriteria/DetachedCriteria out of the repository, in addition with a lot of the business logic being pushed down into infrastructure code it always felt a little dirty.  Whatever approach I’ve taken there has always been some aspect that didn’t feel right, I’ve always been concerned that I’ve have NH—>DB rather than it just being an implementation of the infrastructure that’s wired in at the end, thankfully with NHibernate and Linq there is some light at the end of the tunnel. I’ve haven’t finalised my approach yet, I’ve still got some internal debating to do about location of the query and services and possibly the integrating the specification pattern (now it’s easy to consume), but I think I’m going to take a slight reversal on my previous post.

This is what I’m liking.

public virtual IEnumerable<T> GetByQuery
            (Expression<Func<T, bool>> predicate,
             Func<IQueryable<T>, IQueryable<T>> selectionPredicate)
        {
            using (ITransaction tx = Session.BeginTransaction())
            {
                try
                {
                    IQueryable<T> query = Session.Linq<T>().Where(predicate);
                   return selectionPredicate(query);
                }
                catch (HibernateException hibernateException)
                {
                    tx.Rollback();
                    throw new RepositoryException(hibernateException);
                }
            }
        }
 

In my service layer or outer repository etc..:

 
            Expression<Func<Hotel, bool>> predicate = hotel=>
                  hotel.Stars > 3 && hotel.Country == Country.UK

           Func<IEnumerable<Hotel>,IEnumerable<Hotel>> selectionPredicate = col =>
                          col.Skip(10).Take(10); // pagingSetup.GetQueryForPage(requestedPage);

            var hotels = hotelRepository.GetByQuery(predicate, selectionPredicate);
            return hotels;
   

I fired up Ayende’s cool NH Profiler and the above does get converted to a single neat parameterized SQL statement with correct selection of the paging. This also significantly aids in testability as injecting a in-memory repository in place of NH into the service layer is now super easy just execute the expressions as is on the collection (I won’t even post the code for that)…  In future I might not even be working with NHibernate – so this approach gives me great flexibility with no query logic trapped in HQL or the NH criteria api – who knows – it could be couchdb etc.. :)

Share/Save/Bookmark

Written by matt-csharp

May 24th, 2009 at 7:24 am

Posted in nhibernate

Tagged with , ,

Leave a Reply

Security Code: