Linq Paging с использованием Skip and Take возвращает неправильный результат после первой страницы

У нас есть страница jquery.jtable, реализующая пейджинг. Мы заметили, что пейджинг не совсем работает. Например, если всего 17 элементов, на первой странице правильно отображается 10, а на второй — 7. Однако, если всего 20 элементов, на первой странице отображается 10, а на второй — только 8. Мы используем:

вернуть myQuery.Skip(startIndex).Take(pageSize).ToList()

На второй странице startindex = 10 и размер страницы = 10, и, как я уже сказал выше, возвращается только 8. Похоже, виновником является .Take. Я поместил оператор if прямо над кодом, заменив его следующим образом:

       if (myQuery.Skip(startIndex).ToList().Count() <= pageSize)
       {
          return myQuery.Skip(startIndex).ToList();
       }

На втором проходе If возвращает true, так как и count, и pagesize равны 10. Возврат здесь действительно возвращает все 10 строк второй страницы. Меня беспокоит то, что если полный набор myQuery велик, это может вызвать проблемы с ресурсами. К счастью, эта конкретная таблица содержит небольшое количество строк.

Кто-нибудь еще сталкивался с этим и нашел лучшее решение?


person Joel WZ    schedule 02.10.2015    source источник
comment
Можете ли вы воспроизвести это с помощью короткой, но полной программы, использующей LINQ to Objects? Я ожидаю, что все будет в порядке... (Непонятно, при чем здесь jquery, кстати. То, что jquery делает запросы, не означает, что это часть проблемы. Я бы попытался изолировать проблему настолько, насколько можно, убрав все посторонние аспекты.)   -  person Jon Skeet    schedule 02.10.2015


Ответы (1)


Способ, которым вы получаете startIndex, должен быть виновником. Попробуй это:

return myQuery.Skip((pageNumber - 1 ) * pageSize).Take(pageSize).ToList();

Редактировать:

И убедитесь, что pageNumber никогда не выходит за пределы максимально возможного номера страницы.

var maxPages = maxRecords / pageSize + (maxRecords % pageSize > 0 ? 1 : 0);

Так, например, у вас есть метод для получения только тех записей, которые вы хотите для определенной страницы:

public List<SomeEntity> GetSomeEntityForPage(int pageNumber, int pageSize)
{
    return myQuery.Skip((pageNumber - 1 ) * pageSize).Take(pageSize).ToList(); 
}
person Nicky    schedule 02.10.2015