Подтвердить что ты не робот

Метод "Пропустить" поддерживается только для отсортированного ввода в LINQ to Entities

Что может быть причиной этой проблемы?

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

Любые предложения?

4b9b3361

Ответ 1

Похоже, что ошибка - это именно то, что она говорит. Msgstr "Пропуск разрешен только для сортированных входов". Поиск этой ошибки, я нашел это:

http://weblogs.asp.net/rajbk/archive/2009/09.aspx

Он должен быть исправлен, если вы включили OrderBy перед пропуском:

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

Это может быть проблемой, поскольку вы передаете общий объект T. Возможно, вам нужно будет расширить свой класс, чтобы получить другой параметр, чтобы указать порядок по элементу.

Надеюсь, это поможет.

Ответ 2

который работает (используйте сначала 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

Я хотел проверить это, выполнив эквивалент SQL аналогичного запроса LINQ skip/take.

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

An IQueryable не имеет порядка, поэтому "игнорировать следующие элементы x" не имеет никакого смысла.

Если вы включаете предложение order by (или, возможно, вызов AsEnumerable() - непроверенный), то ваши данные принимают порядок и Skip и Take теперь разумны.