2009-12-11 16 views
11

Gibt es eine "nette" Möglichkeit, eine CAML-Abfrage für SharePoint zu erstellen, die so etwas tut?SQL IN-Äquivalent in CAML

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

Oder bin ich mit einem Alptraum von verschachtelten <Or> Knoten stecken?


EDIT: Das war meine Lösung, um die <Or> Knoten zu generieren.

/// 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); 
} 

Verbrauch:

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

Ausgang:

<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> 

Auch diese Überladung gemacht für mit Lookup Feldern arbeiten ein wenig einfach

/// <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); 
} 

Antwort

5

FullTextSqlQuery

Es ist möglich, MOSS mit SQL-Anweisungen zu suchen, wobei die Klasse FullTextSqlQuery verwendet wird. Ich habe keine Erfahrung, diese Klasse persönlich zu benutzen. Diese Artikel nützlich sein können:

YACAMLQT

Alternativ gibt es auch YACAMLQT (Yet Another CAML Query Tool) die Ihnen erlaubt, Sharepoint CAML-Abfragen mit einem T-SQL zu erstellen Syntax.

LINQ to Sharepoint

Wenn Sie sich mit LINQ zu beschleunigen, dann stellt die LINQ to SharePoint project ein Tool Sharepoint-Listen mit der LINQ-Syntax abzufragen. Bitte beachten Sie, dass sich dieses Tool noch in der Alpha-Testphase befindet und daher möglicherweise nicht produktionsbereit ist.

U2U CAML Query Builder

Wenn Sie mit CAML-Abfragen arbeiten, würde ich empfehlen die U2U CAML Query Builder for SharePoint (2003 und 2007) Tool Ihre CAML-Abfragen aufzubauen. Mit dem Tool können Sie Ihre Abfragezeichenfolge erstellen und sie mithilfe einer Zeigen-und-Klicken-Schnittstelle (siehe unten) gegen die Zielliste ausführen.

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

Von den vier oben genannten Methoden kann ich die U2U CAML Query Builder empfehlen, es fast täglich über die letzten 6 Monaten genutzt haben. Es scheint auch das am häufigsten verwendete CAML-Tool in der SharePoint-Community zu sein.

Hinweis, wenn Sie die CAML-Abfragen in Code erstellen, dann empfehle ich, dass Sie einen Blick auf die CAML.NET project auf CodePlex werfen, die "eine Reihe von.. NET sprachbasierte Tools zur Erstellung von dynamischen, wiederverwendbaren CAML Abfrage Komponenten

+0

Ich wusste nichts über CAML.NET. Möglicherweise müssen Sie das in Zukunft verwenden. Ich habe etwas Ähnliches mit XElements gemacht, um die notwendigen ''s zu erzeugen. – Chris

23

Für diejenigen, mit Sharepoint 2010 gibt es ein IN-Element zur Verfügung:

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

Hier ein funktionierendes Beispiel:

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>"); 
Verwandte Themen