-
Notifications
You must be signed in to change notification settings - Fork 165
Paging and Sorting
Let's first start off with some code examples and then talk through specific points of interest.
public class Order
{
public int OrderId { get; set; }
public string Name { get; set; }
public double Total { get; set; }
public DateTime OrderDate { get; set; }
}
var repo = new InMemoryRepository<Order>();
// get all orders by date descending
var descendingOrders = repo.GetAll(new SortingOptions<Order, DateTime>(x => x.OrderDate, isDescending: true));
// get all orders by Name ascending
var ascendingOrdersByName = repo.GetAll(new SortingOptions<Order, string>(x => x.Name));
// find all orders within the last week, ordered by total amount
var minDate = DateTime.Now.AddDays(-7);
var ordersWithinAWeek = repo.FindAll(x => x.OrderDate > minDate, new SortingOptions<Order, double>(x => x.Total, true));
// sometimes you'll need to sort by multiple properties
// get all orders by date descending, then by name
var sortingOptions = new SortingOptions<Order, DateTime>(x => x.OrderDate, isDescending: true);
sortOptions.ThenSortBy(x => x.Name);
var orders = repo.GetAll(sortOptions);
As you can see the GetAll and FindAll methods have an optional parameter where you can pass in SortingOptions that define the sorting rules. The first generic type is the Entity type, it will always be the same as the Entity type of the repository you are using. The second generic type is the type of the property you are sorting on so you can use an Expression to choose that property. Then there is a true/false for whether you are sorting in descending order (the default is ascending).
There is another way of defining your SortingOptions as well, you can use "magic strings" instead. Now why would you want to do this? Well, for convenience in certain situations. In a web application it may be convenient to post back the name of the property you want to sort on when doing grid displays where the columns are sortable. Here is how you can handle that.
// get all orders by date descending
var descendingOrders = repo.GetAll(new SortingOptions<Order>("OrderDate", isDescending: true));
Instead of passing in a second generic and using an expression you can just send in the property name and it will be found via reflection.
Paging is basically an extension on sorting. For paging you need to provide the page number, number of results per page, and sorting options. So instead of using a SortOptions object you will define and use PagingOptions with GetAll or FindAll.
// 20 results per page, get me page 1 sorted by OrderDate descending
var pagingOptions = new PagingOptions<Order, DateTime>(1, 20, x => x.OrderDate, isDescending: true);
var pageOneOrders = repo.GetAll(pagingOptions);
// get the total results to decide if there should be a next link for pagination display
var totalItems = pagingOptions.TotalItems;
// 20 results per page, get me page 2 sorted by OrderDate descending, then name
pagingOptions = new PagingOptions<Order, DateTime>(2, 20, x => x.OrderDate, isDescending: true)
pagingOptions.ThenSortBy(x => x.Name);
var pageTwoOrders = repo.GetAll(pagingOptions);
You can use paging options with FindAll as well, and you can use the "magic string" approach for the sorting property as well.