Ryan LanciauxNew Media Mercenary

RhinoCommons, NHibernate and ASP.NET MVC Part 5 - LINQ to NHibernate

June 3, 2008 by ryan

Settings 

Up until now, we've been using  NHibernate Query Generator for all of our data access. Although this is a great way to retrieve our data, there is another option we can play around with -- LINQ for NHibernate. To set this up in our existing application (see Part 1, Part 2, Part 3 and Part 4 on creating the ASP.NET MVC Application) we'll first need to grab the code out of subversion https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/experiments/NHibernate.Linq/ and build it using MSBuild or Visual Studio. After that we want to add a reference to it in our application.

Simple Code 

Next we'll want to update our controller to use Linq for NHibernate instead of NHQG (Service layer would be better place for this type of code but since this is a demo it'll be okay -- for more on using a service layer to handle all the repository code check out Michael Hanney's post on ActiveRecord, NHibernate and ASP.NET MVC). The initial NHGQ code is:

var p = Repository<Product>.FindOne(Where.Product.Title == ID);


Our LINQ for NHibernate query will look like this:

            var p = (from item in UnitOfWork.CurrentSession.Linq<Product>()

                        where item.Title == ID

                        select item).First();

It's pretty obvious that the Linq code is a bit longer than the NHQG code. Although that in itself is not a bad thing, it may turn some people away. Momentarily, we'll see some scenarios where Linq for NH is very useful.

Paging and Sorting 

One nice thing we can easily do with Linq for NHibernate is page and sort our data. If we simply want to get a list of all products it would look like this.  

            var p = (from item in UnitOfWork.CurrentSession.Linq<Product>()

                    select item

                    ).ToList()

To page/sort the data it's just a slight addition to the list all code.

            int itemsPerPage = 5;

            int startIndex = (ID.Value - 1)* itemsPerPage;

 

            var p = (from item in UnitOfWork.CurrentSession.Linq<Product>()

                    orderby item.Title ascending

                    select item

            ).Skip(startIndex).Take(itemsPerPage).ToList();


More Advanced Usage

Kyle Baley's article on Linq for Nhibernate shows a more interesting use for Linq for NHibernate; we can create a generic method that adds query criteria on the fly. This would make our code much more reusable so we're going to go ahead and make a demo class heavily based on these concepts.

    public class QueryHandler<T>

    {

        private IList<linqExpression.Expression<Func<T, bool>>>  _criteria;

        public QueryHandler()

        {

            _criteria = new List<linqExpression.Expression<Func<T, bool>>>();

        }

        public void AddCriteria(linqExpression.Expression<Func<T, bool>> LambdaFunc)

        {

            _criteria.Add(LambdaFunc);

        }

 

        public IList<T> GetList()

        {

            var query = from item in UnitOfWork.CurrentSession.Linq<T>()

                        select item;

            //Tack on our query Criteria

            foreach (var criterion in _criteria)

            {

                query = query.Where<T>(criterion);

            }

            return query.ToList();

        }

    }

Here, we've created a class that has a private list of criteria, a method to add criteria to the list and a method to get the list based on the given criteria. I realize it may be a little intimidating but we can perfom most of our select queries through this method due to the use of Generics. 

Updating the controllers to use this functionality is not too difficult. For pages that simply retrieve lists we call the GetList method without specifying any criteria:

            var queryHandler = new QueryHandler<Product>();

            var p = queryHandler.GetList().Skip(startIndex).Take(itemsPerPage).ToList();

 Pass in new lambda expressions to add query criteria

            var queryHandler = new QueryHandler<Product>();

            queryHandler.AddCriteria(item => item.Title == ID);

 

            var p = queryHandler.GetList().First();


Now we see there are multiple options for interacting with our ActiveRecord Repository. Please let me know of any changes that you would make. I've updated the demo code in Assembla -- http://svn2.assembla.com/svn/NHibernateTest - Standard disclaimer does apply (some of the code is less than ideal but for learning it should be okay).

 

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList



Related posts

Comments

June 6. 2008 07:28

pingback

Pingback from allcoolblogs.com

RhinoCommons, NHibernate and ASP.NET MVC Part 5 - LINQ to NHibernate

allcoolblogs.com

June 10. 2008 02:54

pingback

Pingback from blog.cwa.me.uk

Reflective Perspective - Chris Alcock » The Morning Brew #111

blog.cwa.me.uk

June 10. 2008 13:59

Michael Hanney

Ryan, thanks for posting this. Really powerful stuff. I can't wait to start using LINQ to NHibernate in my next project. The paging example is really cool.

Michael Hanney

June 17. 2008 19:51

anonymous

The ServiceClasses\QueryHandler.cs file is missing from the SVN Checkout.

anonymous

June 19. 2008 13:07

Ryan Lanciaux

@Anon: Sorry about that -- I've committed that to SVN. Thanks for the heads up!

Ryan Lanciaux

July 12. 2008 00:44

Nathan Stott

Is using Linq to NHibernate compatible with using the Adaptive Domain Model approach? www.ayende.com/.../...dels-with-Rhino-Commons.aspx

Nathan Stott

July 29. 2008 20:49

pingback

Pingback from hsidev.wordpress.com

To (ASP.NET)MVC or not to MVC (or, ASP.NET MVC Hyperlink Acupuncture) « HSI Developer Blog

hsidev.wordpress.com

July 31. 2008 18:26

pingback

Pingback from hsidev.wordpress.com

So you want to learn NHibernate? - Part 1 of 1, The Links « HSI Developer Blog

hsidev.wordpress.com

August 8. 2008 15:28

pingback

Pingback from thefreakparade.com

So you want to learn NHibernate? (or, NHibernate Hyperlink Acupuncture) | The Freak Parade

thefreakparade.com

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

August 27. 2008 23:30





© 2008 Ryan Lanciaux :: powered by BlogEngine.NET