Как работать с IQueryable подкачки с Linq To Entities? (проблема с OrderBy) - PullRequest
3 голосов
/ 05 октября 2009

В настоящее время я создаю простой сайт ASP.NET MVC, используя Linq to Entities. Моим первым набегом в этот мир был обед для ботаников, в котором я нашел постраничный код списка, который я пытаюсь использовать. Код выглядит следующим образом:

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. Метод 'OrderBy' должен быть вызван перед методом 'Пропустить'.

Не зная все входы и выходы Linq, я не уверен, как добавить в предложение orderby, когда не знаю, какие имена столбцов будут в вышеприведенном методе, что с ним является общим.

Спасибо!

Ответы [ 4 ]

9 голосов
/ 05 октября 2009

Во-первых, я настоятельно рекомендую использовать бесплатный PagedList код, а не писать свой собственный, так как он учитывает многие вещи, которые вам в конечном итоге придется обнаружить самостоятельно, и не имеет почти никаких недостатков. .

Чтобы ответить на ваш вопрос, вы должны отсортировать список, прежде чем передавать его в функцию подкачки. Если вам нужно сделать это динамически, вы можете использовать библиотеку Microsoft DynamicQuery . Но, как правило, вызывающий код знает, как сортировать список.

6 голосов
/ 05 октября 2009

Вы можете изменить сигнатуру конструктора, чтобы потребовать аргумент IOrderedQueryable<T> вместо IQueryable<T>. Тогда вызывающий код будет отвечать за обработку заказа.

public PaginatedList(IOrderedQueryable<T> source, int pageIndex, int pageSize)
4 голосов
/ 05 октября 2009

Я думаю, что ваша лучшая ставка будет состоять в том, чтобы ваши запросы имели заказ до передачи их на PaginatedList.

2 голосов
/ 05 октября 2009

Вы всегда можете добавить другой метод в метод, чтобы позволить вызывающей стороне определить предложение 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));
}
...