Получение всех веб-страниц SPWeb и дочерних веб-сайтов, у которых есть поле со значением в Sharepoint?

У меня есть веб-сайт в Sharepoint 2007. Я хочу сделать запрос, в котором поле «home» веб-страниц равно 1 в одном конкретном SPWeb и (это важная часть) его дочерних SPweb. Я могу заставить это работать с рассматриваемым сайтом, а не с дочерними сайтами. То есть: он не рекурсивный, но я указываю это в предложении «webs scope = 'recursive'».

Я также включаю Список, который хочу использовать, то есть страницы (не документы, главные страницы или что-то еще), поэтому я ищу базовый шаблон «850» (тот, который предназначен для страниц).

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

  string campo="home";
  SPSiteDataQuery qry = new SPSiteDataQuery();

                  qry.Query = "<Where><Eq><FieldRef Name='";
                  qry.Query += campo + "'/><Value
Type='Boolean'>1</Value></Eq>";
                  qry.Query += "</Where><OrderBy><FieldRef

Name = 'Modified' Ascending = 'false'> /> ";

                  qry.Webs = "<Webs Scope='Recursive'/>";
                  qry.ViewFields = "<FieldRef Name='Title'/><FieldRef

Name = 'Изменено' /> ";

 //this gives me system privileges
                  using (SPSite site = new SPSite(CurrentSite.ID,

GetSystemToken (CurrentSite))) {

                      using (SPWeb web = site.OpenWeb("/News/"))
                      {

                          StringBuilder sb = new StringBuilder();

                          sb.Append("<Lists>");

                          foreach (SPList list in web.Lists)
                          {

                              if (list.BaseTemplate.ToString() ==

"850") {

                                  sb.Append("<List ID=\"" +

list.ID.ToString () + "\" /> ");

                              }

                          }

                          sb.Append("</Lists>");
                          qry.Lists = sb.ToString();

                          dt = web.GetSiteData(qry);

                      ..................

Итак, единственное решение, которое я нашел, - это создать цикл после прецедентного кода через Webs, но я не думаю, что это очень оптимизированный способ:

     foreach (SPWeb w2 in web.Webs)
                              {
                                 sb = new StringBuilder();
                                      sb.Append("<Lists>");
                                      foreach (SPList list in w2.Lists)


                           {
                                              if (list.BaseTemplate.ToString() 
== "850")
                                              {

      sb.Append("<List ID=\""
     + list.ID.ToString() + "\"/>");
                                              }
                                          }


                                      sb.Append("</Lists>");
                                              qry.Lists = sb.ToString();

                                          DataTable dttmp = w2.GetSiteData(qry);
                                          if (dttmp != null
 && dttmp.Rows.Count > 0)
                                          {
                                              dt.Merge(dttmp);
                                          }

                                  w2.Dispose();
                              }

person netadictos    schedule 09.03.2009    source источник


Ответы (2)


Наконец, я сделал следующее, я не знаю, что в итоге сработало, я изменил способ запроса списков и включил RowLimit:

DataTable dt = null; DataView dv = null;

    SPSiteDataQuery qry = new SPSiteDataQuery();

    qry.Query = "<Where><Eq><FieldRef Name='";
    qry.Query += campo + "'/><Value Type='Boolean'>1</Value></Eq>";
    qry.Query += "</Where><OrderBy><FieldRef Name='Modified' Ascending='false' /></OrderBy>";
    qry.Webs = "<Webs Scope='Recursive'/>";
    qry.Lists = "<Lists ServerTemplate='850' Hidden='FALSE' MaxListsLimit='50'/>";
    qry.RowLimit = 3;

    qry.ViewFields = "<FieldRef Name='Title'/><FieldRef Name='Modified'/><FieldRef Name='FileRef'/>";

    using (SPSite site = new SPSite(CurrentSite.ID, GetSystemToken(CurrentSite)))
    {
        using (SPWeb web = site.OpenWeb(webUrl))
        {   
            dt = web.GetSiteData(qry);

            dv = dt.DefaultView;

        }
    }

    return dv;
person netadictos    schedule 10.03.2009
comment
Рад, что у вас все наладилось! О, и спасибо за размещение рабочего кода. - person Paul-Jan; 10.03.2009

Вы говорите об установке рекурсивной области веб-сайтов, но в вашем (плохо отформатированном) примере кода вы оставляете свойство веб-сайтов пустым, что означает, что запрос данных сайта будет выполнять поиск только в указанной сети.

Эта конкретная (пропущенная) деталь вашего кода очень важна, потому что даже малейшая орфографическая ошибка в спецификации innerXML незаметно вернет поведение к значению по умолчанию, что означает, что поиск будет выполняться только в текущей сети. Типичной ошибкой является неправильное использование заглавных букв в Webs или Scope.

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

qry.Webs = "<Webs Scope='Recursive' />";

В качестве быстрой проверки вы можете попробовать установить для области SiteCollection, посмотрите, работает ли это.

[Edit] Согласен, теперь ваша собственность Webs отображается, все в порядке :-). Вы пробовали установить атрибут Nullable = 'TRUE' в fieldref поля Campo? Если поле отсутствует (или повреждено или что-то еще) ни на одном из дочерних сайтов, это может помочь. [/ Edit]

person Paul-Jan    schedule 09.03.2009
comment
Извините, но именно редактор скрыл часть, которая казалась плохо отформатированной. Я тоже попробовал SiteCollection. - person netadictos; 10.03.2009
comment
Спасибо за вашу помощь, я сделал что-то другое в конце, не спрашивайте меня, что именно заставило эту работу. - person netadictos; 10.03.2009