Server-side paging, sorting, filtering and grouping with the Kendo UI Grid and NHibernate


What’s the problem?

When using the grid in client-side mode, all the data functions of paging, sorting, filtering and grouping are supported. However when dealing with large volumes of data, all of the data needs to be transmitted prior to performing an operation. This will negatively impact the user experience or cause the operation to fail completely i.e. time-out.

The obvious solution is perform all the operations of paging, sorting, filtering and grouping server-side. Kendo Grid offers two solutions to handling this: LINQ binding and custom binding.

Unfortunately NHibernate’s LINQ does not support the method calls used by the grid’s grouping and generates an exception:

“Specified method is not supported.”

 The alternative is develop a custom binding model, but working with the hierarchy of AggregateFunctions is intricate and complicated.

There is a simpler solution.

The Scenario

The solution was to use a combination of LINQ-NHibernate and LINQ-Objects in order to achieve the desired result. The LINQ-NHibernate runs and executes the paging, sorting and filtering. From the results of that query, LINQ-Objects can do the grouping that the NHibernate library is lacking.

Here’s a code snippet:

  1. private DataSourceResult GetOrdersWithGrouping(DataSourceRequest request)
  2. {
  3.     var session = NHibernateProvider.SessionFactory.OpenSession();
  4.     var orders = session.Query<OrderModel>();
  5.     var grouping = request.Groups;
  6.     //Add ordering for the grouping
  7.     var tempSort = grouping.Select(g => new SortDescriptor()
  8.     {
  9.         Member = g.Member, SortDirection = g.SortDirection
  10.     }).ToList();
  11.     tempSort.Reverse();
  12.     tempSort.ForEach(x => request.Sorts.Insert(0, x));
  13.     //Remove the grouping before exeecuting the query against NHibernate
  14.     request.Groups = null;
  15.     //Execute the query and return results from the database.
  16.     //These results will be paged, filtered and ordered.
  17.     var result = orders.ToDataSourceResult(request);
  18.     var total = result.Total;
  19.     request.Groups = grouping;
  20.     request.Page = 1;
  21.     result = result.Data.ToDataSourceResult(request);
  22.     result.Total = total;
  23.     return result;
  24. }

There are several advantages to this solution:

  • You get to keep using NHibernate for data access.
  • All data operations (filtering, ordering, paging) are performed on the database server.
  • You get to make use of Kendo’s valuable data Grouping functionality in your grids.
  • Clients will love you and shower you with adoration… maybe.

Grouping is grid presentation functionality and since we’re only applying it to a single data page, it does not significantly impact performance. The win is you still get the valuable grid feature of being able to separate and view your data in hierarchical  groups.

Now go forth and be adored…!





%d bloggers like this: