Необходимо преобразовать 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 иногда сообщает о ложных срабатываниях, и их можно игнорировать (прочитайте документацию, чтобы узнать, как это сделать).