2009-12-11 21 views
11

Esiste un modo "carino" per creare una query CAML per SharePoint che faccia qualcosa del genere?SQL IN equivalente in CAML

SELECT * 
FROM table 
WHERE Id IN (3, 12, ...) 

o sto bloccato con un incubo di annidati <Or> nodi?


EDIT: Questa è stata la mia soluzione per generare i nodi <Or>.

/// Simulates a SQL 'Where In' clause in CAML 
/// </summary> 
/// <param name="columnType">Specifies the data type for the value contained by the field.</param> 
/// <returns>Nested 'Or' elements portion of CAML query</returns> 
public static string CamlIn<T>(string internalFieldName, string columnType, T[] values) 
{ 
    XDocument doc = new XDocument(); 
    XElement prev = null; 
    int index = 0; 

    while (index < values.Length) 
    { 
     XElement element = 
      new XElement("Or", 
       new XElement("Eq", 
        new XElement("FieldRef", 
        new XAttribute("Name", internalFieldName)), 
       new XElement("Value", 
        new XAttribute("Type", columnType), 
        values[index++].ToString()))); 

     if (index == values.Length - 1) 
     { 
      element.AddFirst(
       new XElement("Eq", 
        new XElement("FieldRef", 
        new XAttribute("Name", internalFieldName)), 
       new XElement("Value", 
        new XAttribute("Type", columnType), 
        values[index++].ToString()))); 
     } 

     if (prev != null) 
      prev.AddFirst(element); 
     else 
      doc.Add(element); 

     prev = element; 
    } 

    return doc.ToString(SaveOptions.DisableFormatting); 
} 

Usage:

int[] ids = new int[] { 1, 2, 4, 5 }; 
string query = string.Format("<Where>{0}</Where>", CamlIn("SomeColumn", "Number", ids)); 

uscita:

<Where> 
    <Or> 
     <Or> 
      <Or> 
       <Eq> 
        <FieldRef Name=\"SomeColumn\" /> 
        <Value Type=\"Number\">5</Value> 
       </Eq> 
       <Eq> 
        <FieldRef Name=\"SomeColumn\" /> 
        <Value Type=\"Number\">4</Value> 
       </Eq> 
      </Or> 
      <Eq> 
       <FieldRef Name=\"SomeColumn\" /> 
       <Value Type=\"Number\">2</Value> 
      </Eq> 
     </Or> 
     <Eq> 
      <FieldRef Name=\"SomeColumn\" /> 
      <Value Type=\"Number\">1</Value> 
     </Eq> 
    </Or> 
</Where> 

anche fatto questo sovraccarico per il funzionamento con campo di ricerca un po 'più facile

/// <summary> 
/// Simulates a SQL 'Where In' clause in CAML 
/// </summary> 
/// <param name="lookupId">Specify whether to use the Lookup column's Id or Value.</param> 
/// <returns>Nested 'Or' elements portion of CAML query</returns> 
public static string CamlIn<T>(string internalFieldName, bool lookupId, T[] values) 
{ 
    XDocument doc = new XDocument(); 
    XElement prev = null; 
    int index = 0; 

    while (index < values.Length) 
    { 
     XElement element = 
      new XElement("Or", 
       new XElement("Eq", 
        new XElement("FieldRef", 
         new XAttribute("Name", internalFieldName), 
         lookupId ? new XAttribute("LookupId", "TRUE") : null), 
        new XElement("Value", 
         new XAttribute("Type", "Lookup"), 
         values[index++].ToString()))); 

     if (index == values.Length - 1) 
     { 
      element.AddFirst(
       new XElement("Eq", 
        new XElement("FieldRef", 
         new XAttribute("Name", internalFieldName), 
         lookupId ? new XAttribute("LookupId", "TRUE") : null), 
        new XElement("Value", 
         new XAttribute("Type", "Lookup"), 
         values[index++].ToString()))); 
     } 

     if (prev != null) 
      prev.AddFirst(element); 
     else 
      doc.Add(element); 

     prev = element; 
    } 

    if (values.Length == 1) 
    { 
     XElement newRoot = doc.Descendants("Eq").Single(); 
     doc.RemoveNodes(); 
     doc.Add(newRoot); 
    } 

    return doc.ToString(SaveOptions.DisableFormatting); 
} 

risposta

5

FullTextSqlQuery

È possibile cercare MOSS utilizzando istruzioni SQL, utilizzando la classe FullTextSqlQuery. Non ho esperienza di usare questa classe personalmente. Questi articoli possono essere utili:

YACAMLQT

In alternativa, c'è anche YACAMLQT (Yet Another CAML Query Tool) che consente di creare query CAML SharePoint utilizzando una T-SQL sintassi.

LINQ to SharePoint

Se siete al passo con LINQ, allora la LINQ to SharePoint project fornisce uno strumento per interrogare elenchi di SharePoint utilizzando la sintassi LINQ. Si prega di notare che questo strumento è ancora in fase di test alpha, quindi potrebbe non essere pronto per la produzione.

U2U CAML Query Builder

Se si sta lavorando con le query CAML, mi consiglia di utilizzare lo strumento U2U CAML Query Builder for SharePoint (2003 e 2007) per costruire le query CAML. Lo strumento consente di creare la stringa di query e di eseguirla rispetto all'elenco di destinazione, utilizzando un'interfaccia point-and-click, come illustrato di seguito.

U2U CAML Query Builder for SharePoint in action http://www.u2u.net/res/Images/Tools/CQB/buildwhereclause6.png

di quanto sopra quattro metodi, posso consigliare il Query Builder U2U CAML, avendo usato quasi ogni giorno nel corso degli ultimi 6 mesi. Sembra anche essere lo strumento CAML più utilizzato nella comunità di SharePoint.

Nota, se si stanno creando query CAML nel codice, quindi si consiglia di dare un'occhiata allo CAML.NET project su CodePlex, che fornisce "un insieme di.. strumenti linguistici basati su NET per la creazione di dinamiche, riutilizzabili componenti di query CAML"

+0

Non sapeva di CAML.NET. Potrebbe essere necessario usarlo in futuro. Ho fatto qualcosa di simile con XElements per generare il '' s necessario. – Chris

23

Per coloro che utilizzano SharePoint 2010, c'è un elemento in disponibile:

http://msdn.microsoft.com/en-us/library/ff625761.aspx

Ecco un esempio funzionante:

SPQuery locationsQuery = new SPQuery(); 
locationsQuery.Query = string.Concat("<Where>", 
             "<In>", 
             "<FieldRef Name='ID' />", 
              "<Values>", 
              "<Value Type='Number'>6</Value>", 
              "<Value Type='Number'>7</Value>", 
              "<Value Type='Number'>8</Value>", 
              "</Values>", 
             "</In>", 
            "</Where>");