Paging with LINQ for objects
You're looking for the Skip
and Take
extension methods. Skip
moves past the first N elements in the result, returning the remainder; Take
returns the first N elements in the result, dropping any remaining elements.
See MSDN for more information on how to use these methods: http://msdn.microsoft.com/en-us/library/bb386988.aspx
Assuming you are already taking into account that the pageNumber should start at 0 (decrease per 1 as suggested in the comments) You could do it like this:
int numberOfObjectsPerPage = 10;
var queryResultPage = queryResult
.Skip(numberOfObjectsPerPage * pageNumber)
.Take(numberOfObjectsPerPage);
Otherwise if pageNumber is 1-based (as suggested by @Alvin)
int numberOfObjectsPerPage = 10;
var queryResultPage = queryResult
.Skip(numberOfObjectsPerPage * (pageNumber - 1))
.Take(numberOfObjectsPerPage);
Using Skip
and Take
is definitely the way to go. If I were implementing this, I would probably write my own extension method to handle paging (to make the code more readable). The implementation can of course use Skip
and Take
:
static class PagingUtils {
public static IEnumerable<T> Page<T>(this IEnumerable<T> en, int pageSize, int page) {
return en.Skip(page * pageSize).Take(pageSize);
}
public static IQueryable<T> Page<T>(this IQueryable<T> en, int pageSize, int page) {
return en.Skip(page * pageSize).Take(pageSize);
}
}
The class defines two extension methods - one for IEnumerable
and one for IQueryable
, which means that you can use it with both LINQ to Objects and LINQ to SQL (when writing database query, the compiler will pick the IQueryable
version).
Depending on your paging requirements, you could also add some additional behavior (for example to handle negative pageSize
or page
value). Here is an example how you would use this extension method in your query:
var q = (from p in products
where p.Show == true
select new { p.Name }).Page(10, pageIndex);