C# 反向 IQueryable
C# Reverse IQueryable
我正在从另一种方法 (QueryItems
) 中检索有序的 IQueryable<Item>
。我想(有条件地)在传递之前颠倒 IQueryable<Item>
的顺序。
public async Task<PagedList<Item>> GetItems(FilterParameters filterParameters)
{
var items = QueryItems(filterParameters)
if (filterParams.Descending)
{
//do something to reverse the order of the IQueryable
}
return await PagedList<Item>
.CreateAsync(items, filterParams.PageNumber, filterParams.PageSize)
}
我不能做 var reversed = items.ToList().Reverse; items = reversed.AsQueryable()
因为那样它(显然)不能用于异步任务。
当我尝试执行 items = items.Reverse()
时,出现以下错误:
System.NotImplementedException: Remotion.Linq.Clauses.ResultOperators.ReverseResultOperator
主要是因为我很懒,我不想进入 QueryItems
方法来实现 items.OrderByDescending()
,因为那需要一堆 if/else 语句。
那么...如何反转 IQueryable 的顺序?
编辑 - 包括 PagedList.CreateAsync(...)
public class PagedList<T> : List<T>
{
public int CurrentPage { get; set; }
public int TotalPages { get; set; }
public int PageSize { get; set; }
public int TotalCount { get; set; }
public PagedList(List<T> items, int count, int pageNumber, int pageSize)
{
TotalCount = count;
PageSize = pageSize;
CurrentPage = pageNumber;
TotalPages = (int) Math.Ceiling(count / (double) pageSize);
this.AddRange(items);
}
public static async Task<PagedList<T>> CreateAsync(IQueryable<T> source, int pageNumber, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToListAsync();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
}
正如下面的评论所指出的,您几乎肯定想要颠倒整个查询的顺序,这样最后一页就会变成第一页,反之亦然。为此,您别无选择,只能使用 OrderByDescending
。但是,您可以分解出实际的 order by 子句以减少代码重复。例如:
Expression<Func<Item,int>> orderBy = o => o.Id;
注意:上面的int
类型参数对应表达式中属性的类型。根据您实际想要订购的内容,相应地更改右侧的 Id
和左侧的 int
。
然后:
items = filterParams.Descending
? items.OrderByDescending(orderBy)
: items.OrderBy(orderBy);
如何编写一个 ExpressionVisitor
并使用 InterceptedQuery 将所有 OrderBy
和 ThenBy
重写为 OrderByDescending
和 ThenByDescending
以及反之亦然?
我正在从另一种方法 (QueryItems
) 中检索有序的 IQueryable<Item>
。我想(有条件地)在传递之前颠倒 IQueryable<Item>
的顺序。
public async Task<PagedList<Item>> GetItems(FilterParameters filterParameters)
{
var items = QueryItems(filterParameters)
if (filterParams.Descending)
{
//do something to reverse the order of the IQueryable
}
return await PagedList<Item>
.CreateAsync(items, filterParams.PageNumber, filterParams.PageSize)
}
我不能做 var reversed = items.ToList().Reverse; items = reversed.AsQueryable()
因为那样它(显然)不能用于异步任务。
当我尝试执行 items = items.Reverse()
时,出现以下错误:
System.NotImplementedException: Remotion.Linq.Clauses.ResultOperators.ReverseResultOperator
主要是因为我很懒,我不想进入 QueryItems
方法来实现 items.OrderByDescending()
,因为那需要一堆 if/else 语句。
那么...如何反转 IQueryable 的顺序?
编辑 - 包括 PagedList.CreateAsync(...)
public class PagedList<T> : List<T>
{
public int CurrentPage { get; set; }
public int TotalPages { get; set; }
public int PageSize { get; set; }
public int TotalCount { get; set; }
public PagedList(List<T> items, int count, int pageNumber, int pageSize)
{
TotalCount = count;
PageSize = pageSize;
CurrentPage = pageNumber;
TotalPages = (int) Math.Ceiling(count / (double) pageSize);
this.AddRange(items);
}
public static async Task<PagedList<T>> CreateAsync(IQueryable<T> source, int pageNumber, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToListAsync();
return new PagedList<T>(items, count, pageNumber, pageSize);
}
}
正如下面的评论所指出的,您几乎肯定想要颠倒整个查询的顺序,这样最后一页就会变成第一页,反之亦然。为此,您别无选择,只能使用 OrderByDescending
。但是,您可以分解出实际的 order by 子句以减少代码重复。例如:
Expression<Func<Item,int>> orderBy = o => o.Id;
注意:上面的int
类型参数对应表达式中属性的类型。根据您实际想要订购的内容,相应地更改右侧的 Id
和左侧的 int
。
然后:
items = filterParams.Descending
? items.OrderByDescending(orderBy)
: items.OrderBy(orderBy);
如何编写一个 ExpressionVisitor
并使用 InterceptedQuery 将所有 OrderBy
和 ThenBy
重写为 OrderByDescending
和 ThenByDescending
以及反之亦然?