понедельник, 20 августа 2012 г.

Разбиение запроса SPQuery на страницы

Ещё один способ получить большое количество данных – это использовать разбиение запроса на страницы, т.е. получение элементов списка порциями по несколько элементов.

Для этого надо указать объекту класса 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);
    }
}

 

Для моего списка результат выглядит следующим образом (консольное приложение):

image

пятница, 17 августа 2012 г.

Получение большого количества данных из SharePoint или использование ContentIterator

Как правило для получения данных из списков SharePoint мы используем SPQuery. Но если количество возвращаемых элементов велико, то мы можем получить SPQueryThrottleException.

Чтобы этого избежать, необходимо использовать появившийся в SharePoint 2010 класс ContentIterator!

Кроме элементов списков, он также умеет перебирать файлы, списки, сайты, коллекции сайтов, а также элементы или файлы в указанной папке.

Использовать данный класс предельно просто!

Пример:

using (var site = new SPSite("http://x33/"))
{
    using (var web = site.OpenWeb())
    {
        var list = web.Lists["TestList"];

        var itemsTitles = new List<string>();
        
        var iterator = new ContentIterator();
        iterator.ProcessListItems(list, spListItem => itemsTitles.Add(spListItem.Title), (spListItem, exception) => true);
    }
}

 

Методу ProceeListItems нужно указать два делегата – для обработки полученного элемента списка и для обработки ошибок при обращении к данным.

Класс находится в Microsoft.Office.Server.Utilites.

При необходимости ему также можно указать SPQuery, чтобы выбирать только нужные элементы.

Методы перебора других сущностей SharePoint аналогичны.