5 особенностей SPSiteDataQuery

В SharePoint есть механизм, позволяющий выбирать данные из нескольких списков одним запросом. Для этого существует класс SPSiteDataQuery. Проблема в том, что он имеет ряд особенностей. О них сегодня и речь.

Вступление

Мною уже был написан пост о работе с SPSiteDataQuery в SharePoint 2007. С тех пор мало, что изменилось. Особенности остались.

Два списка для примеров расположены на одном сайте и имеют следующий набор полей:

List1:

  • Number (числовой);
  • DateOnly (только дата);
  • DateTime (дата и время)
  • CurrencyUSD (валюта, USD);
  • CurrencyRUB (валюта, RUB);
  • Lookup (ссылка на List1);
  • Lookup2 (ссылка на List1, множественный выбор);
  • Calc1 (вычисляемый, [CurrencyUSD]-[CurrencyRUB]).

List2:

  • DateOnly (только дата);
  • CurrencyEUR (валюта, EUR);
  • Lookup (ссылка на List1, множественный выбор);

Картинка (множественный выбор здесь не отражен):

Простой пример

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

SPSiteDataQuery dataQuery;
dataQuery = new SPSiteDataQuery
    {
        //Custom List
        Lists =  @"<Lists ServerTemplate=""100"" />",
        // Title only
        ViewFields =  @"<FieldRef Name=""Title""/>",
        // Emptyy query
        Query = string.Empty,
        Webs =  @"<Webs Scope=""SiteCollection"" />"
    };
var dt = web.GetSiteData(dataQuery);

Результат:

Поля List, WebId и ID есть всегда.

1. Явно указывать Nullable

Если какое-либо поле отсутствует в списках, из которых извлекаются данные, то необходимо в свойстве ViewFields явно указывать то, что это поле может отсутствовать.

В примере выше изменим свойство ViewFields:

ViewFields =  @"<FieldRef Name=""Title"" /><FieldRef Name=""Lookup"" />",

Поле Lookup есть в обоих списках, но оно заполнено не везде и результат будет пустой. Чтобы этого избежать необходимо добавить атрибут Nullable:

ViewFields =  @"<FieldRef Name=""Title"" /><FieldRef Name=""Lookup"" Nullable=""TRUE"" />",

Теперь в результирующий набор попадают все строки:

Но при этом все эти поля пустые, не смотря на то, что в списках значения есть!

Отсюда следует вторая особенность:

2. Не использовать множественные lookup'ы

Никогда не используйте lookup-поля с множественным выбором. Данные в этом случае не возвращаются. Это относится ко всем lookup-полям: пользователи и метаданные.

3. Не указывать явно поля ListId, WebId, ID

Если вы вдруг захотите проявить всю свою правильность и указать явно поля ListId, WebId или ID, то ничего хорошего из этого не выйдет. Ожидаемых значений вы не получите.

ViewFields =  @"<FieldRef Name='Title' /><FieldRef Name='Id' Nullable='TRUE' /><FieldRef Name='ListId' Nullable='TRUE' /><FieldRef Name='WebId' Nullable='TRUE' />",

Только пустота:

4. Не использовать поля с мета-данными

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

ViewFields = @"<FieldRef Name= 'Title' /><FieldRef Name= 'ServerUrl' Nullable= 'TRUE' /><FieldRef Name= 'EncodedAbsUrl' Nullable= 'TRUE' />"

Результирующий набор содержит данные:

Это тот случай, когда лучше ничего чем правильные данные. То, что возвращает запрос web.GetSiteData() к реальности отношения не имеет. Вот результаты аналогичного запроса List.GetItems():

5. Пользоваться поиском

Если есть необходимость выбирать данные из нескольких списков/библиотек/сайтов/коллекций сайтов, то для этого надо использовать поиск. Работает он крайне быстро и вышеописанных проблем не имеет.

Виталий Жуков

Виталий Жуков

Техлид, Архитектор, Разработчик, Microsoft MVP. Более 20 лет опыта в области системной интеграции и разработки программного обеспечения. Специализируюсь на проектировании и внедрении масштабируемых высокопроизводительных программных решений в различных отраслях.

Смотрите также

Развертывание списков и библиотек с помощью SPFx-решений

Развертывание списков и библиотек с помощью SPFx-решений

SharePoint. Drag-and-Drop Загрузчик файлов

SharePoint. Drag-and-Drop Загрузчик файлов

CSOM. Загрузка файлов

CSOM. Загрузка файлов

SharePoint List REST API. Часть 2

SharePoint List REST API. Часть 2

SharePoint Framework. Создание веб-части на Angular

SharePoint Framework. Создание веб-части на Angular

SharePoint List REST API. Часть 1

SharePoint List REST API. Часть 1

Презентация с доклада о SharePoint Framework

Презентация с доклада о SharePoint Framework

SharePoint Framework. Создаем AngularJS 1.x Client WebPart

SharePoint Framework. Создаем AngularJS 1.x Client WebPart

SharePoint. Регистрация CSS и JavaScript с помощью DelegateControl

SharePoint. Регистрация CSS и JavaScript с помощью DelegateControl

SharePoint. Расширяем REST API

SharePoint. Расширяем REST API

SharePoint Excel Services. Создаем кредитный калькулятор

SharePoint Excel Services. Создаем кредитный калькулятор

SharePoint Ribbon API. Использование ToggleButton

SharePoint Ribbon API. Использование ToggleButton

SharePoint 2013. How To: настройка входящей почты для разработчиков

SharePoint 2013. How To: настройка входящей почты для разработчиков

Мифы и правда о Linq to SharePoint

Мифы и правда о Linq to SharePoint

SharePoint 2013. Введение в SharePoint App. Часть 2

SharePoint 2013. Введение в SharePoint App. Часть 2

SharePoint 2013. Введение в SharePoint App. Часть 1

SharePoint 2013. Введение в SharePoint App. Часть 1

Превью для веб-части в SharePoint 2010/2013

Превью для веб-части в SharePoint 2010/2013

SharePoint 2013. Еще немного о новых контролах

SharePoint 2013. Еще немного о новых контролах

SharePoint 2013. Контрол ClientPeoplePicker

SharePoint 2013. Контрол ClientPeoplePicker

SharePoint 2013. Контрол ImageCrop

SharePoint 2013. Контрол ImageCrop

SharePoint 2013. Тип поля Geolocation

SharePoint 2013. Тип поля Geolocation

Создание типа поля в SharePoint

Создание типа поля в SharePoint

SharePoint 2010. Длительные операции с обновляемым статусом

SharePoint 2010. Длительные операции с обновляемым статусом

Linq to SharePoint. Создаем ContentIterator

Linq to SharePoint. Создаем ContentIterator

Linq to SharePoint. Получение данных из другой коллекции сайтов

Linq to SharePoint. Получение данных из другой коллекции сайтов

Linq to SharePoint. Версионность

Linq to SharePoint. Версионность

SharePoint. Получение URL-адреса иконки для документа

SharePoint. Получение URL-адреса иконки для документа

SharePoint 2010. PostBack для Fluent Ribbon API

SharePoint 2010. PostBack для Fluent Ribbon API

Linq to SharePoint. Блокировка документов

Linq to SharePoint. Блокировка документов

Linq to SharePoint. Паттерн Repository

Linq to SharePoint. Паттерн Repository

Linq to SharePoint. Получение мета-данных списка

Linq to SharePoint. Получение мета-данных списка

Linq to SharePoint. Мапинг полей

Linq to SharePoint. Мапинг полей

Linq to SharePoint. Формирование данных для ProcessBatchData

Linq to SharePoint. Формирование данных для ProcessBatchData

Linq to SharePoint. Сравнение производительности с Camlex.NET

Linq to SharePoint. Сравнение производительности с Camlex.NET

Linq to SharePoint. Часть 5. Поля Choice и MultiChoice

Linq to SharePoint. Часть 5. Поля Choice и MultiChoice

Linq to SharePoint. Часть 4. Dynamic LINQ

Linq to SharePoint. Часть 4. Dynamic LINQ

Linq to SharePoint. Особенности. Часть 3

Linq to SharePoint. Особенности. Часть 3

Linq to SharePoint. Особенности. Часть 2

Linq to SharePoint. Особенности. Часть 2

SharePoint 2010. PeopleEditor. Установка значения

SharePoint 2010. PeopleEditor. Установка значения

SharePoint 2010. Настройка входящей почты для кастомного списка

SharePoint 2010. Настройка входящей почты для кастомного списка

Linq to Sharepoint. Особенности

Linq to Sharepoint. Особенности

EntityFramework. Оптимистические блокировки

EntityFramework. Оптимистические блокировки