Ещё один способ получить большое количество данных – это использовать разбиение запроса на страницы, т.е. получение элементов списка порциями по несколько элементов.
Для этого надо указать объекту класса SPQuery значения для свойств ListItemCollectionPosition и RowLimit.
RowLimit – указывает сколько элементов списка необходимо получить.
Свойство ListItemCollectionPosition – это объект класса SPListItemCollectionPosition принимающий в конструкторе строковой параметр, в котором указано с какого элемента необходимо получить данные (точнее следующего за ним элемента). Выглядит это так: “Paged=TRUE&p_ID=5” – получить элементы после элемента с ID равным 5.
Например, сделаем такой метод:
private static SPListItemCollection GetPagedItems(SPList list, string pagingInfo, uint rowLimit) { var query = new SPQuery { RowLimit = rowLimit, ListItemCollectionPosition = new SPListItemCollectionPosition(pagingInfo) }; return list.GetItems(query); }
Метод возвращает заданное количество элементов (rowLimit) из указанной страницы (pagintInfo).
Если в pagingInfo передавать пустую строку, то метод вернёт первую страницу.
Возвращаемые методом данные (типа SPListItemCollection) содержат в себе данные для получения следующей страницы – свойство ListItemCollectionPosition.
Таким образом, мы можем организовать постраничную загрузку и обработку элементов списка, например следующим образом (используя вышеприведённый метод):
using (var site = new SPSite("http://mysite/")) { using (var web = site.OpenWeb()) { var list = web.Lists["TestList"]; var pagingInfo = string.Empty; //Здесь храним информацию о странице var pageNumber = 1; //Номер страницы, для оформления вывода SPListItemCollection items = null; //Полученные данные do { if (items != null && items.ListItemCollectionPosition != null) pagingInfo = items.ListItemCollectionPosition.PagingInfo; //Получаем данные о странице из предыдущего запроса Console.WriteLine("Page {0}, Info '{1}'", pageNumber, pagingInfo); items = GetPagedItems(list, pagingInfo, 5); //Получаем по 5 элементов foreach (SPListItem item in items) Console.WriteLine(item.Title); Console.WriteLine(); pageNumber++; } while (items.ListItemCollectionPosition != null); } }
Для моего списка результат выглядит следующим образом (консольное приложение):
Вот сколько писал код для SP - почти ни разу не потребовалось использовать paging в коде. Даже ContentIterator очень редко использовал.
ОтветитьУдалитьМожет есть примеры как сделать какое-либо полезное решение с этим кодом?
Мне пришлось использовать пейджинг при аггрегации нескольких списков в JsGrid.
УдалитьА развертывание пейджинга (т.е. последовательное получение всех элементов с помощью пейджинга) требовалось при выгрузке этого аггрегированного представления в Excel.
Так что задачи потенциально есть. Но редко.
Я сам никогда не пользовался - ни ContentIterator, ни разбиением SPQuery на страницы.
УдалитьНо думаю задачи всё равно у кого-нибудь найдутся, так пусть он найдёт ответ хотя бы тут! :)
Опять же, чтобы обойти SPQueryThrottleException, когда получаем очень много элементов.
ОтветитьУдалитьДругих примеров применения думаю не будет.
Разве что, когда отображаем только определённую страницу элементов, но тут нужно ещё поизвращаться, чтобы найти ID последнего элемента на предыдущей странице.
Вот тоже грешен, ContentIterator - вообще не использовал , а вот с педженгом возится приходилось, но давно. Но вот я опой чую что всю выборку надо делать через ContentIterator + paging , так сказать патерн разработать и юзать его везде и всегда, что бы спалось по ночам хорошо и не переживать что у тебя в решении SPQueryThrottleException вылетит :)
ОтветитьУдалитьКстати да, а то х/з когда у них там за 5 тыщ элементов перевалит... :)
УдалитьМеня может рядом уже не оказаться...
> Опять же, чтобы обойти SPQueryThrottleException, когда получаем очень много элементов.
ОтветитьУдалитьА зачем получать "очень много элементов"?
Разные задачи же могут быть...
УдалитьНапример, передача их куда-нибудь, или построение отчёта по ним.
Проще писать в базу в момент изменения, чем использовать paging.
УдалитьПричём тут писать в базу, если нам данные вытащить надо!
Удалить