关于linq:C#Reverse IQueryable

C# Reverse IQueryable

我正在从另一个方法(QueryItems检索一个有序的IQueryable)。我想(有条件地)颠倒IQueryable的顺序,然后再进行传递。

1
2
3
4
5
6
7
8
9
10
11
12
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(…)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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。但是,您可以考虑实际的ORDERBY子句,以减少代码重复。例如:

1
Expression<Func<Item,int>> orderBy = o => o.Id;

注意:上面的int类型参数与表达式中的属性类型相对应。根据您实际想要订购的商品,相应地更改右侧的Id和左侧的int

然后:

1
2
3
items = filterParams.Descending
    ? items.OrderByDescending(orderBy)
    : items.OrderBy(orderBy);


写一个ExpressionVisitor并使用截获的查询将所有OrderByThenBy重新写入OrderByDescendingThenByDescending,反之亦然?