Reputation: 5619
I have the following LINQ join:
var query = _ABC.Table
.Join(_DEF.Table, cef => ...etc... })
.Join(_GHI.Table, extf => ...etc...})
.Select(jcefn=> new { XYZ = jcefn....etc...});
The linq is good and returns what I expect (verified in LINQ pad).
I am the trying to pass the query into an extension method with this signature:
public PagedList(IQueryable<T> source, int pageIndex, int pageSize)
{ ... }
So I thought this would be acceptable:
var FPaged = new PagedList<MyObject>(query.ToList(), pageIndex, pageSize);
But that apparently isn't making the compiler happy. It is saying:
Argument 1: cannot convert from 'System.Collections.Generic.List' to 'System.Linq.IQueryable etc.
So obviously I need to change my linq anonymous type but not sure exactly what to change it to?
Note I did NOT include alot of code for brevity thinking it wasn't needed for understanding but I will gladly edit it in if needed.
Thank You
Upvotes: 3
Views: 1511
Reputation: 13819
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.
Upvotes: 2
Reputation: 1502376
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);
Upvotes: 10
Reputation: 8579
Get rid of the ToList(). You need an IQueryable not an IList
var FPaged = new PagedList(query, pageIndex, pageSize);
Upvotes: 6