Пейджинг и сортировка на стороне сервера Лучшая практика?

Я использую следующий метод, чтобы получить данные для моей подсетки jqgrid, и он отлично работает.

Обратите внимание, что этот метод используется для реализации сортировки и разбиения по страницам на стороне сервера.

Теперь у меня есть запрос, как вы можете видеть в строке

List<SomeEntity> myList = _service.GetSomeData(id); здесь выполняется вызов базы данных и извлекаются все записи.

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

public JsonResult GetData(string folderId, string sidx, string sord, int page, int rows) {
    int id = int.Parse(folderId);
    List < SomeEntity > myList = _service.GetSomeData(id);

    const int pageSize = 5;

    // total
    double totalPages = Math.Ceiling((double) myList.Count() / pageSize);

    // sort
    if (sord == "asc") {
        myList = myList.OrderBy(m = > m.Name).ToList();
    }
    else {
        myList = myList.OrderByDescending(m = > m.Name).ToList();
    }

    // paging
    myList = myList.Skip((page - 1) * pageSize).Take(pageSize).ToList();

    var jsonData = new {
        total = totalPages, records = domainList.Count, page,

        rows = myList
    };

    return Json(jsonData, JsonRequestBehavior.AllowGet);
}​

person Yasser Shaikh    schedule 21.09.2012    source источник
comment
Вопрос, который вы, возможно, должны задать себе, если это совершенно необходимо. Вы можете выполнять разбиение по страницам и сортировку через внешний интерфейс, используя множество различных компонентов (slickgrid, jqGrid, таблицы данных и т. д.), которые могут обрабатывать большие объемы данных. В чем причина желания сделать это на стороне сервера?   -  person mbx-mbx    schedule 21.09.2012
comment
как правило, обработка его на стороне сервера уменьшает объем данных, отправляемых клиенту, что удобно, если они находятся на жестком соединении. также означает, что при переходе между страницами будут учитываться любые новые данные, введенные с момента загрузки первой страницы.   -  person logical Chimp    schedule 21.09.2012
comment
К счастью, в наши дни веревочные соединения составляют меньшинство, поскольку у большинства людей есть широкополосное соединение. Этот сайт случайно не будет использоваться с мобильных устройств?   -  person mbx-mbx    schedule 21.09.2012
comment
@logicalChimp Согласен, но есть способы справиться с этим с помощью временных меток. Я делаю очень похожие вещи, но через регулярные промежутки времени спрашиваю сервер «что изменилось с этой метки времени» (через ajax), и я получаю только последние изменения, которые обычно очень малы (а затем динамически обновляю сетку). Первоначально первая загрузка страницы получает наибольшее количество данных (поскольку timstamp равен 0), но у нас не было проблем с большими объемами данных json.   -  person mbx-mbx    schedule 21.09.2012
comment
Если вы используете сортировку/пейджинг на стороне клиента, как вы справляетесь с ситуацией, когда IE7/8 с более чем 200 записями работает очень медленно?   -  person Kevin B    schedule 21.09.2012
comment
@Magrangs Проблема с пейджингом на стороне клиента заключается в том, что в большинстве ситуаций первая страница — это все, что когда-либо требуется, поэтому, извлекая и отправляя только эту одну страницу, вы улучшите производительность (часто значительно) создания этой страницы. Когда пользователю нужно больше, чем просто первая страница, он также вряд ли будет использовать больше, чем несколько страниц. Просмотр более чем нескольких страниц, как правило, довольно необычен.   -  person Servy    schedule 21.09.2012
comment
Что касается этого вопроса, я обычно выполняю фильтрацию и сортировку с помощью запроса к базе данных, он, как правило, более оптимизирован для этой задачи. Я не вижу ничего плохого в том, что вы делаете.   -  person Kevin B    schedule 21.09.2012
comment
Может быть важно знать, как определяется _service.GetSomeData(id). Используете ли вы Entity Framework или LINQ To SQL? Какой тип возвращает _service.GetSomeData(id)? Ни в коем случае вы не должны преобразовывать _service.GetSomeData(id) в List<T> для обработки подкачки и сортировки **на стороне SQL-сервера, а не в вашей программе на C#, как вы делаете сейчас.   -  person Oleg    schedule 21.09.2012
comment
@Servy Думаю, это зависит от ситуации и от того, веб-сайт это или веб-приложение. Кроме того, в сочетании с кэшированием на стороне сервера в нашей ситуации только самый первый запрос страницы получает наибольший объем данных (что также не является проблемой с точки зрения скорости). Последующие запросы выполняются очень быстро, без проблем с разбиением по страницам и сортировкой больших объемов данных на стороне клиента.   -  person mbx-mbx    schedule 21.09.2012
comment
@KevinB Не поддерживает IE7 и имеет минимальную поддержку IE8. Также используйте компонент, который может обрабатывать эти большие наборы данных, например slickgrid или datatables. (нам повезло в нашей ситуации, когда нам не нужно поддерживать эти старые браузеры)   -  person mbx-mbx    schedule 21.09.2012
comment
@Magrangs К сожалению, это не всегда решение разработчиков.   -  person Kevin B    schedule 21.09.2012
comment
@KevinB Да, я согласен, хотя так и должно быть ;-)   -  person mbx-mbx    schedule 21.09.2012
comment
@Magrangs only the very first page request receives the largest amount of data ТОЧНО! Первая страница будет просматриваться чаще, чем все остальные вместе взятые. Люди обычно находят то, что им нужно, на первой странице большинства результатов с разбивкой на страницы в целом и добавляют к этому людей, переходящих на страницу, когда им вообще не нужно было просматривать результаты (попали не на ту страницу, не знали, что именно). был там, просто осматривался и т. д.). Первая страница любого набора данных с разбивкой на страницы должна быть максимально оптимизирована.   -  person Servy    schedule 21.09.2012
comment
В лучшем случае я бы извлек только первую страницу при ее просмотре, а затем при просмотре любой другой страницы извлекал бы либо все страницы (если все разумно), либо группу из нескольких страниц и страницу на стороне клиента с этого момента, но это больше работы, поэтому на практике часто не стоит беспокоиться.   -  person Servy    schedule 21.09.2012
comment
@Servy Как правило, на веб-сайтах, да, в веб-приложениях, где у пользователя может быть большое количество задач, но не всегда. В любом случае, я не собираюсь вступать в дискуссию (эти комментарии и так достаточно велики).   -  person mbx-mbx    schedule 21.09.2012
comment
@KevinB Просто для справки вот пример обработки 500 000 строк slickgrid. Также я считаю, что единственным браузером, который не поддерживается, является IE6 :-) mleibman .github.com/SlickGrid/examples/   -  person mbx-mbx    schedule 21.09.2012
comment
ВАУ ! с чего мне начать @All, я хочу работать на стороне сервера, потому что в будущем у меня будут миллионы записей   -  person Yasser Shaikh    schedule 21.09.2012


Ответы (2)


Похоже, вы возвращаете все данные из своей службы (_service), а затем подкачиваете результаты. Кроме того, похоже, что вы будете делать один и тот же запрос каждый раз, когда делается запрос на пейджинг. Если это правда, то я думаю, что это неэффективно.

Ваша служба (_service) должна обрабатывать функции Take and Skip (передавать как параметры), тем самым уменьшая количество записей, которые извлекаются и отправляются по сети. Вы не опубликовали код для своего метода GetSomeData(id). Возвращает ли он IEnumerable или IQueryable? Это также будет иметь отношение к производительности/эффективности.

Надеюсь, я правильно понял ваш код или вопрос.

person Big Daddy    schedule 21.09.2012
comment
да, вот и все, у меня должны быть методы взятия и пропуска, используемые при запросе моей базы данных, и я должен извлекать только необходимые данные, а это 5 за раз. Спасибо чувак ! - person Yasser Shaikh; 21.09.2012

Ваша основная проблема заключается в том, что вы назначаете результат _service.GetSomeData(id) List<SomeEntity>. В любом случае вы должны использовать ObjectQuery<SomeEntity> или IQueryable<SomeEntity> (в зависимости от используемой технологии базы данных), чтобы иметь возможность использовать сортировку и очистку на стороне SQL Server. Ваш текущий код просто получает все данные, затем сортирует их и получает нужную страницу в следующем операторе. Я мог бы порекомендовать вам посмотреть код из ответа или более свежий код из еще один ответ дополнительные примеры того, как сортировка, разбиение на страницы и фильтрация данных могут быть реализованы для jqGrid.

person Oleg    schedule 21.09.2012