2009-10-13 27 views
11

Belirli bir klasöre ayrılmış, belirli bir klasöre ayrılmış, bu noktadan sonra yinelenen ve tüm ListItems (bir ölçütle eşleşen) ve Klasörler döndüren bir CAML sorgusu yazmaya çalışıyorum .Sonuç kümesindeki klasörleri içeren CAML sorgusu

İşte (okunabilirlik için biçimlendirilmiş) çalışması lazım gibi görünüyor sorgu için kod:

SPQuery query = new SPQuery(); 
query.Query = " 
<Where> 
    <Or> 
     <Contains> 
      <FieldRef Name=\"FileRef\" /> 
      <Value Type=\"Text\">foo</Value> 
     </Contains> 
     <Eq> 
      <FieldRef Name=\"FSObjType\" /> 
      <Value Type=\"Lookup\">1</Value> 
     </Eq> 
    </Or> 
</Where>"; 

query.ViewFields = " 
<FieldRef Name=\"CustomField1\" Nullable=\"TRUE\" /> 
<FieldRef Name=\"CustomField2\" Nullable=\"TRUE\" /> 
<FieldRef Name=\"CustomField3\" Nullable=\"TRUE\" /> 
"; 

query.RowLimit = 500; 
query.ViewAttributes = "Scope=\"RecursiveAll\""; 
query.Folder = startingFolder; 
DataTable dt = myList.GetItems(query).GetDataTable(); 

Yani - hayır klasörleri - Bu sadece ListItems döndürür.

Sorgudan diğer koşulları kaldırırsam, yalnızca FSObjType=1'u bırakıyorum, bir COM istisnası alıyorum "Bu eylemi tamamlayama. Lütfen tekrar deneyin."

ViewFields'ı kaldırırsam, yalnızca Scope=RecursiveAll ve FSObjType=1'u bırakarak boş bir sonuç ayarlıyorum.

+0

Bunu hiç çözdünüz mü? Aynı problemim var ve bir çözüm olmadıkça, devam etmek ve aslında bunu yapmak için özyinelemeli bir işlev yazmam gerekecek. – jeremcc

+0

@codeflunky maalesef, bunu düzgün bir şekilde çalışmadım. –

+0

@codeflunky Eğer bir çözüm bulursanız, lütfen buraya gönderin! –

cevap

5

Test için test etme yetkim yok, bu yüzden daha sonra gözden geçirmem gerekebilir; ama belirli bir öğe için klasör yolunu almak için SPUtility.GetUrlDirectory(url) kullanmanızı sağlayacak öğeler alınıyor

query.ViewAttributes = "Scope=\"Recursive\""; 

denemek ve oradan klasör hiyerarşisini ayrıştırmak düşünüyorum.

+1

"Özyinelemeli" klasörleri derinden arar ancak sonuç kümesindeki klasör nesnelerini içermez. İhtiyacım olan tüm bilgileri tek bir seferde almak istiyorum. Sorgunun üst kısmında onlarca API çağrısı yapmak idealin altında. –

+0

Bunu sorabilirmiysek, bunu tembel yükleme kullanabilen bir ağaç görünümü gibi bazı UI öğesi için sağlayıcı olarak mı kullanıyorsunuz? Yoksa her şeyi tek bir geçişte mi çekeceksin? – gn22

+0

@Gurdas her şeyin bir seferde getirilmesi gerekiyor –

1

Sorgudan diğer koşulları kaldırırsam, yalnızca FSObjType = 1'i bırakıyorum, bir COM istisnası alıyorum "Bu işlem tamamlanamıyor. Lütfen tekrar deneyin."

Bunu yaptığınızda <Or> etiketlerini kaldırdınız mı? Değilse doğru şekilde çalışmayacaktır.

Bu sorununuzu çözmez. Sorguyu boş bırakmayı denediniz mi? Bir şey döndürüyor mu?

Benzer bir şey üzerinde çalışıyorum ve issue'a da rastladım, belki biraz ilgili.

+0

Evet, tüm CAML sorgularım gereksiz bir 'gibi sözdizimi hatalarından kaçınmak için programsal olarak oluşturulur. Bu bir sözdizimi problemi değil. –

+0

Sorguyu boş bırakırsanız sonuç kümesi alır mısınız? – Mark

+0

Geç cevap için özür dilerim. Tüm koşulları kaldırırsam sonuç kümesini alırım. –

5

Sen

<FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value> 

bu koyarak çözdük

Query.ViewAttributes = "Scope=\"RecursiveAll\""; 
+0

Bunu denedim, aynı sonuçlarla. –

+0

Bu benim için çalıştı. RecursiveAll kullanarak klasörler içinde yer alan klasörler için klasör içerik türüne göre sorgulama yapabildim. –

3

şekilde korurken yerine yazın Klasör İçeriği üzerinde caml sorgusu dayandırarak deneyebilirsiniz:

<QueryOptions> 
<IncludeAttachmentUrls>True</IncludeAttachmentUrls> 
<Folder/> </QueryOptions> 

Farklı sorgu seçeneği Ben yığın taşması üzerine bu konuda sorumu bulundu:

How can I iterate recursively though a sharepoint list using webservices?

+0

İlginç ... Bunu deneyeceğim. Boş klasör etiketinin başarması gereken nedir? –

+0

Klasörü döndürmeli, ancak şu anda hatırlayamıyorum. SPList çok karmaşık ve belirsiz bir web servisidir, bazen sihirdir ... :) Çalışmıyorsa, belgelerimi burada denetlerim. –

1

Bu hala SP 2010. bir sorun gibi görünüyor Burada web hizmetleri kullanan this MSDN Forums post dayalı 2007 veya 2010 için çalışacak geçici çözüm kodu verilmiştir:

private static SPListItem RecurseIntoFolders(SPList list, SPFolder parentFolder, string fileReference) 
{ 
    var query = new SPQuery 
    { 
     Query = "<Where>" + 
       "<Eq><FieldRef Name='FSObjType'/><Value Type='Lookup'>1</Value></Eq>" + 
       "</Where>", 
     ViewFields = String.Format("<FieldRef Name='{0}' />", FileReferenceInternalFieldName), 
     ViewAttributes = "Scope='RecursiveAll'", 
     Folder = parentFolder 
    }; 

    var items = list.GetItems(query); 
    if (items.Count == 0) 
     return null; 

    foreach (SPListItem item in items) 
    { 
     parentFolder = item.Folder; 

     // TODO: Any other checking that this is the item we want 

     return item; 
    } 
    return RecurseIntoFolders(list, parentFolder, fileReference); 
} 
14

Herkes yakındır, ancak tam olarak doğru değil.Her şeyden önce

using (SPSite site = new SPSite("http://server/site")) 
{ 
    SPWeb web = site.RootWeb; // See disposal guidance http://blogs.msdn.com/b/rogerla/archive/2008/10/04/updated-spsite-rootweb-dispose-guidance.aspx 

    SPQuery query = new SPQuery(); 
    query.Query = @" 
      <Where> 
      <BeginsWith> 
       <FieldRef Name='ContentTypeId' /> 
       <Value Type='ContentTypeId'>0x0120</Value> 
      </BeginsWith> 
      </Where>"; 
    query.ViewAttributes = "Scope='RecursiveAll'"; 
    SPList list = web.Lists[listId]; 
    SPListItemCollection items = list.GetItems(query); 
    // Do stuff with your folders 
} 

, bu FieldRef kullanarak yanlıştır: klasör içerik türü kalıtsal olabilir

<FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value> 

çünkü. Bu nedenle, bu gibi içerik türü kimliği karşı karşılaştırmak gerekir: Sonra

<Where> 
    <BeginsWith> 
    <FieldRef Name='ContentTypeId' /> 
    <Value Type='ContentTypeId'>0x0120</Value> 
    </BeginsWith> 
</Where> 

Ve görünümü olan içerik türü Klasör miras alınan her ürün iade edilmelidir O RecursiveAll

<View Scope='RecursiveAll'>...</View> 

Kapsam'ı bağlıyor set (0x0120)

+0

Scope = 'RecursiveAll' için çok teşekkür ederim –

0
static string GetParentFolder(SPListItem itemToFind, SPFolder folder) 
    { 
     SPQuery query = new SPQuery(); 
     // query.Query = "<OrderBy><FieldRef Name='Title'/></OrderBy>"; 
     query.Query = "<Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"Integer\">"+ itemToFind.ID +"</Value></Eq></Where>"; 
     query.Folder = folder; 
     query.ViewAttributes = "Scope=\"Recursive\""; 
     SPListItemCollection items = itemToFind.ParentList.GetItems(query); 
     int intpartentFolderID=0 ; 
     if (items.Count > 0) 
     { 
     foreach (SPListItem item in items) 
     { 

      SPFile f = item.Web.GetFile(item.Url); 

      string test11 = f.ParentFolder.Name; 
      intpartentFolderID = f.ParentFolder.Item.ID; 

      //string test1 = item.File.ParentFolder.Name; 

      return (intpartentFolderID.ToString()); 

     } 
     } 
     return (intpartentFolderID.ToString());  
    }