【发布时间】:2022-01-19 03:12:50
【问题描述】:
我有一个包含ApplyFilter() 方法的分页类,它过滤当前页面的行。由于分页通常只对排序的结果有意义,因此此方法接受并返回 IOrderedQueryable<T>(而不仅仅是 IQueryable<T>)。
我是这样使用的:
var query = DbContext.Items
.Where(i => i.Value > 0)
.OrderBy(i => i.SortColumn);
query = pagination.ApplyFilter(query);
但是我的ApplyFilter() 方法有问题。
public IOrderedQueryable<T> ApplyFilter<T>(IOrderedQueryable<T> query)
{
return query.Skip((CurrentPage - 1) * PageSize).Take(PageSize);
}
Skip() 和Take() 方法都返回一个IQueryable<T>,所以我收到一个错误,返回值无法从IQueryable<T> 转换为IOrderedQueryable<T>。
如何在使用Skip() 和Take() 的同时仍然拥有IOrderedQueryable<T>?
【问题讨论】:
-
查询没有应用
ThenBy的顺序。将其作为 IOrderedQueryable 是没有意义的。该接口存在的全部意义在于确保ThenBy仅可用于直接响应OrderBy调用。 -
@Servy:是的,但这会很好。你可以从我调用它的代码中看到,重载也返回
IOrderedQueryable<T>会很方便。 -
尝试声明查询已订购的缺点似乎明显超过了在不再需要使用的已订购查询上简单地调用
AsQueryable的成本ThenBy(或者简单地使用一个新变量,这通常是更好的选择,变量使用起来并不昂贵)。为手头的问题使用正确的解决方案。将有序查询视为一般查询很好,将无序查询视为已订购只会给自己带来麻烦。 -
@Servy:很好。太糟糕了
AsQueryable()必须分配额外的对象。我不认为这是最小的开销。 -
您认为它将分配哪些对象?它的开销大大比您想出的将查询变成有序可查询的任何可能的实现都少(这永远不可能避免代码中不会在运行时抛出的任何分配)。
AsQueryable除了改变对象的编译时类型之外什么也没做。
标签: c# entity-framework entity-framework-core iqueryable .net-6.0