score:2

Accepted answer

PagedList requires an IQueryable<MyQuery>. Your query object is of type IQueryable<anonymous-type>. To get an IQueryable<MyQuery> you need to change your select to:

var query = _ABC.Table
            .Join(_DEF.Table, cef => ...etc... })
            .Join(_GHI.Table, extf => ...etc...})
            .Select(jcefn=> new MyObject(){ XYZ = jcefn....etc...});

You do not need .ToList() to turn this into an IQueryable, it already is.

However, if you do want to execute and cache the IQueriable before passing it to the function, you could do

var cachedQuery = query.ToList();
var FPaged = new PagedList<MyObject>(cachedQuery.AsQueryAble<MyObject>(), pageIndex, pageSize);

In most cases this is not what you want. The PagedList requires an IQueryable most likely because it will only retrieve the part of the data that is currently needed for a particular page, leaving the rest of the potentially huge dataset behind the query in the database.

But if you actually want to retrieve all the data only once, and then later turn it into a PagedList, this is the way to go. You can then also reuse the cachedQuery in other places, without causing another database retrieval.

score:6

Get rid of the ToList(). You need an IQueryable not an IList

var FPaged = new PagedList(query, pageIndex, pageSize);

score:10

Well yes - query.ToList() will return a List<T>, which doesn't implement IQueryable<T>. Indeed, the ToList() would render the paging less useful, as it would all be done locally after fetching the whole table into memory.

Just get rid of the call to ToList() and it may well be fine.

EDIT: Okay, if it's not fine because of the anonymous type, adding a ToList call isn't going to help. You either want to use a query which projects to an IQueryable<MyObject>, or if you really want a paged query for the anonymous type, you could add an extension method:

public static class PagingExtensions
{
    public static PagedList<T> Paginate<T>(this IQueryable<T> source,
                                           int pageIndex, int pageSize)
    {
        return new PagedList<T>(source, pageIndex, pageSize);
    }
}

Then you can use:

// TODO: Use a more sensible variable name
var FPaged = query.Paginate(pageIndex, pageSize);

Related Articles