Как оптимизировать этот запрос EF и реализовать пейджинг?

У меня около 14 000 строк данных. Если использовать следующий запрос EF, его загрузка занимает много времени, потому что я подозреваю, что он загружает все 14 000 строк, и только после этого выполняется дополнительная фильтрация. Это мой метод Select в моем репозитории.

Public Function SelectAll() As IEnumerable(Of be_Posts) Implements IPostRepository.SelectAll
       Dim posts As IEnumerable(Of be_Posts)
       Using db As Ctx = New Ctx
           posts = db.be_Posts.OrderByDescending(Function(x) x.DateCreated).ToList
           Return posts
       End Using

И контроллер:

Function Index(page As Integer?) As ActionResult
        Dim PageSize = System.Web.Configuration.WebConfigurationManager.AppSettings("PageSize")
        Dim pageNumber As Integer = If(page, 1)
        Dim posts = _repo.SelectAll()
        Return View(posts.ToPagedList(pageNumber, PageSize))
    End Function

Помощник в представлении:

@Html.PagedListPager((Model), Function(page) Url.Action("Index", New With { _
       .page = page _
        }), PagedListRenderOptions.ClassicPlusFirstAndLast)

Теперь, если добавить в предложение take, например .Take(500), все будет работать значительно быстрее. Как я могу сделать этот запрос быстрее и при этом работать будут все записи? Я также использую расширение PagedList Троя Гуда, чтобы получить функциональность пейджинга. Все в порядке, пока я получаю всего несколько сотен записей. Так что делать? Большинство, если не все примеры пейджинга, которые я могу найти, использующие библиотеку Троя, включают весь код непосредственно в контроллер.


person Ashok Padmanabhan    schedule 20.07.2014    source источник
comment
Создан ли какой-то индекс по дате, чтобы SQL Server мог эффективно находить первые X записей? И вы должны вернуть IQueryable   -  person ta.speot.is    schedule 20.07.2014


Ответы (1)


Вызов ToList выполняет запрос и, как вы говорите, получает все записи. Пейджинг выполняется с использованием Skip и Take, например.

Dim page = list.Skip(pageSize * (pageNumber - 1)).Take(pageSize)

Список источников может быть самой таблицей или результатом вызова Where или OrderBy или чем-то еще. Просто убедитесь, что ToList или, что предпочтительнее, ToArray вызывается последним.

person jmcilhinney    schedule 20.07.2014
comment
Как передать pageSize и PageNumber в репозиторий из представления/контроллера? - person Ashok Padmanabhan; 20.07.2014
comment
Как бы вы передавали значения фильтра? Вы делаете это так же. - person jmcilhinney; 21.07.2014
comment
Я заработал. Skip и Take работают нормально. Теперь у меня проблемы с рендерингом помощника пейджера. - person Ashok Padmanabhan; 21.07.2014