Paging and sorting is a common need in ASP.NET applications. GridView itself have a default paging and sorting mechanism. Default paging has performance issues while manipulating large amounts of data. So people use a custom paging mechanism. This way they must note that only needed data must be extracted from database. For example when page 3 just shows 10 records from 21 to 30, there is no reason to load all data from database. With sorting there is two problem. First: default sorting mechanism only work with few specific data sources like Typed DataSet and not every other data sources like those come from NHibernate or Castle ActiveRecord. Second: default sorting sorts only current page not all data.
In order to have an efficient paging and proper sorting mechanism we should use custom paging and custom sorting. Scott Mitchell has a great tutorial series on paging and sorting with GridView. These series are based on an object data source of typed DataSets. So as I’m working with Castle ActiveRecord as my data access layer, I was unable to use Scott’s solution. So I decided to create my own solution using Castle Active Record based on Scott’s original solution.
Doing paging and sorting with Castle Active Record is very very easy. Because Castle ActiveRecord has an API dedicated to paging and sorting: SlicedFindAll. In my solution, firstly I have added 2 method to a typical domain class named Company, secondly notice GridView’s markup that has no codebehind at all. Notice that all my domain classes are inheriting from ActiveRecordBase:
public static Company FindAll(int maximumRows, int startRowIndex, string sortExpression)
orders = new Order;
orders = new Order;
const string DESC = " DESC";
orders = Order.Desc(sortExpression.Replace(DESC, string.Empty));
orders = Order.Asc(sortExpression);
return SlicedFindAll(startRowIndex, maximumRows, orders);
public static int TotalCount()
<asp:GridView runat="server" ID="gvCompany" AllowPaging="true" AllowSorting="true"
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="Tel" HeaderText="Tel" SortExpression="Tel" />
<asp:BoundField DataField="Field" HeaderText="Field" SortExpression="Field" />
<asp:ObjectDataSource runat="server" ID="odsCompany" TypeName="MyDomainNamespace.Company"
SelectMethod="FindAll" EnablePaging="True" SelectCountMethod="TotalCount" SortParameterName="sortExpression" />