我有以下LINQ加入:
var query = _ABC.Table
.Join(_DEF.Table, cef => ...etc... })
.Join(_GHI.Table, extf => ...etc...})
.Select(jcefn=> new { XYZ = jcefn....etc...});
linq很好并且返回我期望的内容(在LINQ pad中验证)。
我试图将查询传递给具有此签名的扩展方法:
public PagedList(IQueryable<T> source, int pageIndex, int pageSize)
{ ... }
所以我认为这是可以接受的:
var FPaged = new PagedList<MyObject>(query.ToList(), pageIndex, pageSize);
但这显然不会让编译器感到满意。它说:
参数1:无法从'System.Collections.Generic.List'转换为'System.Linq.IQueryable等。
所以显然我需要更改我的linq匿名类型但不确定要将其更改为什么?
注意我没有包含很多代码以简洁,认为它不需要理解,但我很乐意在需要时编辑它。
谢谢
答案 0 :(得分:10)
是的 - query.ToList()
将返回List<T>
,但不会实现IQueryable<T>
。实际上,ToList()
会使分页变得不那么有用,因为在将整个表提取到内存之后,它将全部在本地完成。
只是摆脱对ToList()
的号召,它可能会很好。
编辑:好的,如果由于匿名类型不合适,添加ToList
电话无济于事。您要么使用投影到IQueryable<MyObject>
的查询,要么您真的想要匿名类型的分页查询,您可以添加扩展方法:
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);
}
}
然后你可以使用:
// TODO: Use a more sensible variable name
var FPaged = query.Paginate(pageIndex, pageSize);
答案 1 :(得分:6)
摆脱ToList()。你需要一个IQueryable而不是IList
var FPaged = new PagedList(query, pageIndex, pageSize);
答案 2 :(得分:2)
PagedList需要IQueryable<MyQuery>
。您的查询对象的类型为IQueryable<anonymous-type>
。要获得IQueryable<MyQuery>
,您需要将您的选择更改为:
var query = _ABC.Table
.Join(_DEF.Table, cef => ...etc... })
.Join(_GHI.Table, extf => ...etc...})
.Select(jcefn=> new MyObject(){ XYZ = jcefn....etc...});
您不需要.ToList()将其转换为IQueryable,它已经是。
但是,如果你想在将IQueriable传递给函数之前执行并缓存它,你可以这样做
var cachedQuery = query.ToList();
var FPaged = new PagedList<MyObject>(cachedQuery.AsQueryAble<MyObject>(), pageIndex, pageSize);
在大多数情况下,这不是你想要的。 PagedList最有可能需要IQueryable,因为它只会检索特定页面当前所需的部分数据,而将剩余的潜在巨大数据集留在数据库中的查询后面。
但是如果你真的想要只检索一次所有数据,然后再把它变成一个PagedList,这就是你要走的路。然后,您还可以在其他位置重用cachedQuery,而不会导致其他数据库检索。