代码之家  ›  专栏  ›  技术社区  ›  Sergio Tapia

方法“skip”只支持linq to实体中已排序的输入。

  •  15
  • Sergio Tapia  · 技术社区  · 15 年前

    是什么导致了这个问题?

    public ActionResult Index(int page = 0)
    {
        const int pageSize = 3;
        var areas = repo.FindAllAreas();
        var paginatedArea = new PaginatedList<Area>(areas, page, pageSize);
    
        return View(paginatedArea);
    }
    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace UTEPSA.Controllers
    {
        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);
    //ERROR HERE->>this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize));
            }
            public bool HasPreviousPage
            {
                get
                {
                    return (PageIndex > 0);
                }
            }
            public bool HasNextPage
            {
                get
                {
                    return (PageIndex + 1 < TotalPages);
                }
            }
        }
    }
    

    有什么建议吗?

    4 回复  |  直到 6 年前
        1
  •  24
  •   Uwe Keim    6 年前

    似乎错误正是它所说的。”只有排序的输入才允许跳过。正在搜索此错误, I've found this .

    如果在跳过之前包含orderby,则应修复此问题:

    source.orderBy(???).Skip(PageIndex * PageSize).Take(PageSize)); 
    

    这可能是一个问题,因为您正在传递一个通用对象t。您可能需要扩展类来接收另一个参数来指示order by元素。

        2
  •  3
  •   mavore    14 年前

    这是有效的(使用第一个iorderedqueryable):

    http://msdn.microsoft.com/en-us/library/bb738702.aspx

     IOrderedQueryable<Product> products = context.Products
            .OrderBy(p => p.ListPrice);
    
    IQueryable<Product> allButFirst3Products = products.Skip(3);
    
    Console.WriteLine("All but first 3 products:");
    foreach (Product product in allButFirst3Products)
    {
        Console.WriteLine("Name: {0} \t ID: {1}",
            product.Name,
            product.ProductID);
    }
    
        3
  •  2
  •   Peter Shen    9 年前

    我想通过运行类似于linq skip/take查询的SQL等价物来验证这一点。

    SELECT * FROM [table]
    --order by [column] //omitted!
    OFFSET 10 ROWS
    FETCH NEXT 15 rows only
    

    注意,当省略ORDER BY子句时,SQL错误的信息量要少得多:

    "Invalid usage of the option NEXT in the FETCH statement."
    

    所以“排序输入”实际上是数据库级别所必需的。感谢Linq帮助开发人员编写高级SQL语句!

        4
  •  1
  •   Zooba Necrolis    15 年前

    IQueryable 没有命令,所以说“忽略下一个” X 元素“没有任何意义。

    如果包括 order by 条款(或可能是 AsEnumerable() 调用- 未经测试的 )然后,您的数据接受命令 Skip Take 现在是明智的。