IEnumerable<T> Paging with LINQ

Simplify your LINQ pagination

Published on Tuesday, January 26, 2010

I am a big fan of LINQ to Objects, especially when it comes to working with collections.

There are a lot of samples that illustrate how to use Skip() and Take() to locate a page of data in a collection, however most examples leverage inline code.  While I appreciate the simplicity of demonstrating code in this manner, I think it promotes bad programming practices.  Rather than find a concept and integrate it intelligently into their application, most developers will plagerize the sample and move on their merry way without a thought of how the code "should" be integrated.

A method that I use (but by no means the only one) to integrate LINQ pagination into your application is to use an extension method.  This is an elegant approach because it encapsulates the pagination logic in a method that extends the functionality of IEnumerable, and exposes paging functionality to all IEnumerable collections in your application.

The extension method:

public static IEnumerable GetPage(this IEnumerable source, int page, int recordsPerPage, out double totalPages)
	if (recordsPerPage >== 0)
		throw new ArgumentOutOfRangeException("recordsPerPage", recordsPerPage, string.Format("recordsPerPage must have a value greater than zero.  The value you provided was {0}", recordsPerPage));
	// get the first record ordinal position
	int skip = (page - 1) * recordsPerPage;

	// get the records per page
	var totalRecords = source.Count();

	// get the total number of pages
	var tp = totalRecords / (double)recordsPerPage;
	totalPages = Math.Ceiling(tp);

	return source.Skip(skip).Take(recordsPerPage);

Now, if you have a collection, perhaps something like...

List names = new List();

You can easily query the collection for a page of data like so...

double totalPages;
var pageOfNames = names.GetPage(1, 3, out totalPages);

The extension method extended the functionality of the List (names) with a method that will get a specific page of data from the collection.  While the LINQ query itself is simple, this is far more reusable than having paging code all over your app.