I took this from Nerd Dinner and elsewhere,
public class PaginatedList<T> : List<T> {
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; }
public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize) {
PageIndex = pageIndex;
PageSize = pageSize;
TotalCount = source.Count();
TotalPages = (int) Math.Ceiling(TotalCount / (double)PageSize);
this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
}
public bool HasPreviousPage {
get {
return (PageIndex > 0);
}
}
public bool HasNextPage {
get {
return (PageIndex+1 < TotalPages);
}
}
}
What is causing the IQueryable deferred query to run? Is it because AddRange accepts IEnumerable? AddRange itself returns void.
What is causing the IQueryable deferred query to run?
Internally, List<T>.AddRange
enumerates the IEnumerable
, which causes the query to execute.
If you want to defer that, you'd have to override AddRange
and most all other List<T>
members to execute the query, then pass through to the base implementation.
I don't see the benefit of deferring the query.
I totally missed the Count
call. That will execute a similar query (basically the raw query wrapped in a COUNT(*)
outer query) which might be a concern as well. If the query is very complex and takes a long time to execute a count, this could be a source of performance issues as well.