posts - 81, comments - 262, trackbacks - 0

Paging Helpers in Unifico, Filtered and Sorted Paging

Unifico has a few paging helpers to make service methods easily paged from a client. Essentially the framework makes consuming a page request object as simple as calling .ToList() on an IQueryable source. The object, the PageRequest, has two collections, Filters and Sorts with several constructors to make instantiation easy. The collections are rather straight forward, providing filtering and sorting ability on a paging source. The uniqueness comes from the ability to request multiple filters and sorts together, along with a paging request. This request is then execute on the IQueryable source, so if DLINQ is used, results in exactly two database hits. A COUNT statement is executed to find out how many pages there are, and a single select statement providing the paged results. This is all done without exposing LINQ or IQueryable to the service's client.

Making an existing source page-able is rather simple, compare the two implementations.

Without paging implemented:


   44         public List<App.Account.Models.Role> GetRoles()

   45         {

   46             return accountRepository.GetRoles().ToList();

   47         }



With paging implemented:


   43         public PageResponse<App.Account.Models.Role> GetRolePage(PageRequest PageRequest)

   44         {

   45             return accountRepository.GetRoles().ToPageResponse(PageRequest);

   46         }



Utilizing the paging is almost painfully easy.

Grabbing the first page at a size of ten:


  120 PageResponse<Role> rolePage = accountService.GetRolePage(new PageRequest(0, 10));



Or grabbing the first page sorting by the role's name (ascending):


  120             PageResponse<Role> rolePage = accountService.GetRolePage(new PageRequest(0, 10, "Name", "string", true));



Or fully defining the page request:


  120             accountService.GetRolePage(new PageRequest

  121             {

  122                 Index = 2,

  123                 PageSize = 10,

  124                 Filters = new ContractList<Filter>(

  125                     new[]{new Filter { BinaryExpression=FilterBinaryExpression.Equal, Parameter="Name", TypeName="String",Value="Admin"},

  126                         new Filter { BinaryExpression=FilterBinaryExpression.GreaterThan, Parameter="Level", TypeName="Int32", Value=1}}),

  127                 Sorts = new ContractList<Sort>(

  128                     new[] { new Sort { Ascending = true, TypeName = "Int32", Parameter = "Level" } })

  129             });

  130             /* Executes

  131             SELECT [t1].[RoleID] AS [ID], [t1].[Name], [t1].[Level] AS [Level]

  132             FROM (

  133                 SELECT ROW_NUMBER() OVER (ORDER BY [t0].[Level]) AS [ROW_NUMBER], [t0].[RoleID], [t0].[Name], [t0].[Level]

  134                 FROM [dbo].[Role] AS [t0]

  135                 WHERE ([t0].[Level] > 1) AND ([t0].[Name] = 'Admin')

  136                 ) AS [t1]

  137             WHERE [t1].[ROW_NUMBER] BETWEEN 20 + 1 AND 20 + 10

  138             ORDER BY [t1].[ROW_NUMBER]

  139             */



I'm sure you have notice the TypeName properties and wondered why they are there. They enable the helper's methods to work with the expression tree before the query has been executed. Notice that the paging occurs in SQL against the table names and columns, not against the models. While the syntax is nowhere near that of LINQ, it seals of the service and keeps the paging responsibility within the service without requiring the service to handle specific paging requests. A similar method can be used to search multiple sources, and will be added shortly. Ohh, and it works across WCF.


The Unifico Framework

Print | posted on Wednesday, December 31, 2008 8:59 PM | Filed Under [ Web Programming ]

Powered by:
Powered By Subtext Powered By ASP.NET