3

我目前正在使用 Linq to Entities 构建一个简单的 ASP.NET MVC 站点。我第一次涉足这个世界是书呆子晚餐,在那里我找到了我正在尝试使用的分页列表代码。代码如下所示:

public class PaginatedList<T> : List<T>
{

    public int PageIndex { get; private set; }
    public int PageSize { get; private set; }
    public int TotalCount { get; private set; }
    public int TotalPages { get; private set; }

    public PaginatedList(IQueryable<T> source, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        PageSize = pageSize;
        TotalCount = source.Count();
        TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);

        this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
    }

    public bool HasPreviousPage
    {
        get
        {
            return (PageIndex > 0);
        }
    }

    public bool HasNextPage
    {
        get
        {
            return (PageIndex + 1 < TotalPages);
        }
    }
}

问题是我使用的是实体框架,上面的代码抛出以下错误:

仅 LINQ to Entities 中的排序输入支持“跳过”方法。必须在方法“Skip”之前调用方法“OrderBy”。

不知道 Linq 的来龙去脉,当我不知道上述方法中的列名是什么时,我不确定如何添加 orderby 子句,它是通用的。

谢谢!

4

4 回答 4

9

首先,我强烈建议使用免费的PagedList代码而不是编写自己的代码,因为它考虑了许多您最终必须自己发现的东西,并且几乎没有缺点。

要回答您的问题,您应该在将列表传递给分页函数之前对其进行排序。如果需要动态执行此操作,可以使用 Microsoft DynamicQuery库。但通常,调用代码会知道如何对列表进行排序。

于 2009-10-05T15:58:13.003 回答
6

您可以将构造函数的签名更改为需要一个IOrderedQueryable<T>参数,而不是IQueryable<T>. 然后调用代码将负责处理排序。

public PaginatedList(IOrderedQueryable<T> source, int pageIndex, int pageSize)
于 2009-10-05T15:58:04.100 回答
4

我认为你最好的选择是确保你的查询传递给PaginatedList.

于 2009-10-05T15:56:51.883 回答
2

您始终可以向该方法添加另一个参数,以允许调用者定义 OrderBy 子句:

public PaginatedList(IQueryable<T> source, Func<T, TKey> orderBy, 
    int pageIndex, int pageSize)
{
    // your other code here
    this.AddRange(source.OrderBy(orderBy)
        .Skip(pageIndex * pageSize)
        .Take(pageSize));
}
于 2009-10-05T15:59:32.130 回答