2009-10-13 11 views
11

Sto provando a scrivere una query CAML eseguita su uno SPList specifico, con scope in una cartella specifica, ricorsiva da quel punto e restituisce tutti i ListItems (che soddisfano un criterio) e le cartelle .Query CAML che include le cartelle nel set di risultati

Ecco il codice per la query che sembra dovrebbe funzionare (formattato per migliorare la leggibilità):

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(); 

Quindi - restituisce questo solo i ListItems - nessuna cartella.

Se rimuovo le altre condizioni dalla query, lasciando solo il FSObjType=1, viene visualizzata un'eccezione COM "Impossibile completare questa azione. Riprovare".

Se quindi rimuovo ViewFields, lasciando solo il Scope=RecursiveAll e FSObjType=1, ottengo un risultato vuoto impostato indietro.

+0

Hai mai risolto questo? Ho lo stesso problema e, a meno che non ci sia una soluzione, avrò bisogno di andare avanti e in realtà scrivere una funzione ricorsiva per farlo. – jeremcc

+0

@codeflunky purtroppo no, non ho mai funzionato correttamente. –

+0

@codeflunky se trovi una soluzione, per favore postala qui! –

risposta

5

Non ho la mia immagine di dev per testare, quindi potrei aver bisogno di rivederlo più tardi; ma credo che si potrebbe provare

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

Recupero gli oggetti vi permetterà di utilizzare SPUtility.GetUrlDirectory(url) per ottenere il percorso della cartella per un determinato elemento, e analizzare la gerarchia delle cartelle da lì.

+1

"Ricorsivo" cerca le cartelle in profondità ma non include gli oggetti cartella nel set di risultati. Mi piacerebbe avere tutte le informazioni di cui ho bisogno in un round trip - fare dozzine di chiamate API in cima alla query è tutt'altro che ideale. –

+0

Se posso chiedere, stai usando questo come un provider per alcuni elementi dell'interfaccia utente come una visualizzazione ad albero che può utilizzare il caricamento lazy? O dovrai tirare tutto su un solo passaggio? – gn22

+0

@Gurdas tutto deve essere recuperato in una volta –

1

Se rimuovo le altre condizioni dalla query, lasciando solo FSObjType = 1, viene visualizzata un'eccezione COM "Impossibile completare questa azione. Riprovare".

Hai rimosso i tag <Or> quando l'hai fatto? In caso contrario, non funzionerà correttamente.

Indipendentemente da ciò, questo non risolve il problema. Hai provato a lasciare la query vuota? Restituisce qualcosa?

Ho lavorato su qualcosa di simile e ho trovato un issue, forse è un po 'correlato.

+0

Sì, tutte le mie query CAML sono generate a livello di codice per evitare errori di sintassi come un ' superfluo'. Questo non è un problema di sintassi. –

+0

Ottenete un set di risultati se lasciate la query vuota? – Mark

+0

Ci scusiamo per la risposta tardiva. Ricevo un set di risultati di elementi solo se rimuovo tutte le condizioni. –

5

Si potrebbe provare a basare la query caml sul contenuto delle cartelle tipo, invece,

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

pur mantenendo la

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

L'ho provato, con gli stessi risultati. –

+0

Questo ha funzionato per me. Sono stato in grado di eseguire una query per tipo di contenuto della cartella per le cartelle nidificate nelle cartelle utilizzando RecursiveAll. –

3

Ho risolto questo mettere:

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

Come query option

Ho trovato la mia domanda su di esso sulla pila di overflow:

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

+0

Interessante ... Farò un tentativo. Qual è il tag della cartella vuoto che dovrebbe essere realizzato? –

+0

Dovrebbe restituire la cartella, ma non riesco a ricordare in questo momento. SPList è un webservice molto complicato e oscuro, a volte è magico ... :) Se non funziona, controllerò i miei documenti qui. –

1

Questo sembra essere ancora un problema in SP 2010. Ecco il codice soluzione che funziona per il 2007 o il 2010, sulla base this MSDN Forums post che utilizza i servizi web:

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

Tutti sono vicini, ma non del tutto ragione.

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 
} 

Prima di tutto, usando questo FieldRef è sbagliato:

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

perché il tipo di contenuto della cartella può essere ereditata. Pertanto, è necessario confrontare contro l'ID del tipo di contenuto, in questo modo:

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

E poi, impostare la vista attributo scope per RecursiveAll

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

Questo dovrebbe restituire qualsiasi elemento il cui tipo di contenuto eredita dalla cartella (0x0120)

+0

Grazie mille per Scope = 'RecursiveAll' –

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());  
    } 
Problemi correlati