Search code examples
c#paginationlinq-to-entitiesienumerableiqueryable

What will trigger an Entity Framework IQueryable query, in a helper class that inherits List<T>?


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.


Solution

  • 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.

    EDIT

    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.