The method 'Skip' is only supported for sorted input in LINQ to Entities

自古美人都是妖i 提交于 2020-06-10 02:19:14

问题


What could be causing this problem?

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);
            }
        }
    }
}

Any suggestions?


回答1:


Seems like the error is exactly what it is says. "Skip is only allowed on Sorted inputs". Searching for this error, I've found this.

It should be fixed if you include an OrderBy before Skip:

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

Which might be a problem since you are passing a generic object T. You might need to expand your class to receive another parameter to indicate the order by element.




回答2:


that is worked (use first 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:


I wanted to validate this by running the SQL equivalent of a similar LINQ skip/take query.

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

Note that when the order-by clause is omitted, the SQL error is much less informative:

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

So the "sorted input" is actually required on the database-level. Kudos to LINQ for helping developers write advanced SQL statements!




回答4:


An IQueryable does not have an order, so saying "ignore the next x elements" doesn't make any sense.

If you include an order by clause (or possibly an AsEnumerable() call - untested) then your data takes an order and Skip and Take are now sensible.



来源:https://stackoverflow.com/questions/3437178/the-method-skip-is-only-supported-for-sorted-input-in-linq-to-entities

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!