I finally broke down and wrote a standard extension method for IQueryable
/// <summary>
/// Gets a single page of items from a sequence.
/// </summary>
/// <typeparam name="T">The data type of the result items.</typeparam>
/// <param name="query">The sequence</param>
/// <param name="pageNumber">The page number to retrieve, starting at 1.</param>
/// <param name="pageSize">The number of items in each page.</param>
/// <param name="pageCount">Provides the total number of pages available.</param>
/// <returns></returns>
public static IEnumerable<T> TakePage<T>(this IQueryable<T> query, int pageNumber, int pageSize, out int pageCount)
{
int itemCount;
return TakePage(query, pageNumber, pageSize, out pageCount, out itemCount);
}
/// <summary>
/// Gets a single page of items from a sequence.
/// </summary>
/// <typeparam name="T">The data type of the result items.</typeparam>
/// <param name="query">The sequence</param>
/// <param name="pageNumber">The page number to retrieve, starting at 1.</param>
/// <param name="pageSize">The number of items in each page.</param>
/// <param name="pageCount">Provides the total number of pages available.</param>
/// <param name="itemCount">Provides the total number of items availabe.</param>
/// <returns></returns>
public static IEnumerable<T> TakePage<T>(this IQueryable<T> query, int pageNumber, int pageSize, out int pageCount, out int itemCount)
{
if (pageNumber < 1)
throw new ArgumentException("The value for 'page' must be greater than or equal to 1", "pageNumber");
itemCount = query.Count();
pageCount = (int)Math.Ceiling((double)itemCount / (double)pageSize);
if (pageNumber > pageCount)
pageNumber = pageCount;
if (pageNumber > 1)
return query.Skip((pageNumber - 1) \* pageSize).Take(pageSize);
else
return query.Take(pageSize);
}