Необходимо преобразовать SPQuery для одной библиотеки документов в SPSiteDataQuery для всех библиотек документов на сайте

Мне нужна помощь в преобразовании следующего фрагмента кода для использования SPSiteDataQuery вместо SPQuery b/c. Мне нужно выполнять запросы по всем библиотекам документов на сайте.

Вот оригинальный код:

using (SPWeb oWeb = new SPSite(properties.SiteId).OpenWeb(properties.RelativeWebUrl))
                {
                    SPList oList = oWeb.Lists["Quality Documents"];

                    //create query
                    SPQuery oQuery = new SPQuery();

                    //configure the query  //
                    oQuery.Query = "<Where><Eq><FieldRef Name='Document_x0020_Number' /><Value Type='Text'>" + docNum + "</Value></Eq></Where>";

                    //get the collection of items in the list
                    SPListItemCollection oItems = oList.GetItems(oQuery);

                    if (oItems.Count > 0)
                    {
                        newRnd = 0;
                    }
                    else
                    {
                        newRnd = 1;
                    }
                }

И вот что у меня есть для SPSiteDataQuery, но я не знаю, правильно ли это и / или как убедиться, что код выполняет то же самое, что и код выше.

SPSiteDataQuery q = new SPSiteDataQuery();
q.Lists = "<Lists BaseType='1'/>";
q.Query = "<Where><Eq><FieldRef Name='Document_x0020_Number' /><Value Type='Text'>" + docNum + "</Value></Eq></Where>";
q.Webs = "<Webs Scope='SiteCollection' />";
q.ViewFields = "<FieldRef Name='Document_x0020_Number' />"';
q.RowLimit = 1;

1 ответ

Решение

Основное различие между SPQuery и SPSiteDataQuery заключается в указании списка для запроса. В отличие от SPQuery, в SPSiteDataQuery вы не можете указать заголовок списка, чтобы сузить запрос на каждом сайте, у вас есть только элемент Lists, который гораздо менее гибок. Винсент Ротвелл описывает все возможности здесь.

Эта негибкость означает, что использование BaseType=1 в коде элемента Lists вернет документы из всех библиотек документов. Единственный способ избежать этого - развернуть пользовательский шаблон списка для Quality Documents со своим идентификационным номером. Тогда вы сможете использовать <Lists ServerTemplate='XYZ' /> (где XYZ - идентификационный номер, чтобы сузить результаты до этого типа списка). В противном случае вам нужно будет отфильтровать полученные результаты, чтобы они содержали только записи из Quality Documents библиотека.

Помимо этого ваш код выглядит эквивалентно. Вы также можете посмотреть на CrossListQueryInfo и CrossListQueryCache, если вы используете MOSS. Это позволяет вам кэшировать запросы в стиле SPSiteDataQuery. Посмотрите это сообщение Джеффом Далтоном для хорошей информации об этом.

Обновление от комментариев об утилизации объекта:

Ваш код будет пропускать объект SPSite - для этого также требуется условие использования. Замените строку использования, которая у вас есть на данный момент, этими строками:

using (SPSite oSite = new SPSite(properties.SiteId))
using (SPWeb oWeb = oSite.OpenWeb(properties.RelativeWebUrl))
{
    // Your code
}

Кроме того, SPDisposeCheck легко использовать. Для интеграции с Visual Studio добавьте следующую строку в событие пост-сборки вашего проекта:

"% ProgramFiles% \ Microsoft \ SharePoint Dispose Check \ SPDisposeCheck.exe" $ (TargetPath)

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

Другие вопросы по тегам