2009-12-11 9 views
11

¿Existe una "buena" forma de crear una consulta CAML para SharePoint que haga algo como esto?SQL IN equivalente en CAML

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

o estoy atascado con una pesadilla de nodos anidados <Or>?


EDIT: Este fue mi solución para generar los nodos <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); 
} 

Uso:

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

Salida:

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

también hizo esta sobrecarga para trabajar con campos de búsqueda un poco más fácil

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

Respuesta

5

FullTextSqlQuery

Es posible buscar MOSS usando instrucciones SQL, usando la clase FullTextSqlQuery. No tengo experiencia en usar esta clase personalmente. Estos artículos pueden ser de utilidad:

YACAMLQT

Como alternativa, también hay YACAMLQT (Yet Another CAML Query Tool) que le permite crear consultas CAML SharePoint usando un T-SQL sintaxis.

LINQ to SharePoint

Si no está al día con LINQ, entonces el LINQ to SharePoint project proporciona una herramienta para consultar las listas de SharePoint utilizando la sintaxis de LINQ. Tenga en cuenta que esta herramienta todavía se encuentra en la fase de prueba alfa, por lo que puede no estar lista para producción.

U2U CAML Query Builder

Si está trabajando con las consultas CAML, yo recomendaría el uso de la herramienta U2U CAML Query Builder for SharePoint (2003 y 2007) para construir sus consultas CAML. La herramienta le permite construir su cadena de consulta y ejecutarla contra la lista de objetivos, utilizando una interfaz de apuntar y hacer clic, como se muestra a continuación.

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

De los cuatro métodos anteriores, puedo recomendar el Generador de consultas de U2U CAML, habiendo utilizado casi a diario durante los últimos 6 meses. También parece ser la herramienta CAML más utilizada en la comunidad de SharePoint.

Tenga en cuenta que si está creando las consultas CAML en el código, entonces le recomiendo que eche un vistazo al CAML.NET project en CodePlex, que proporciona "un conjunto de.. herramientas basadas en el lenguaje .NET para crear, componentes de consulta CAML reutilizables dinámicas"

+0

No sabía nada de CAML.NET. Puede necesitar usar eso en el futuro. Hice algo similar con XElements para generar el '' s necesario. – Chris

23

Para aquellos que utilizan Sharepoint 2010, no es un elemento en disposición:

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

Aquí está un ejemplo de trabajo:

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