Pregunta

¿Hay una manera "agradable" para crear una consulta CAML para SharePoint que hace algo como esto?

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);
}
¿Fue útil?

Solución

no, tendrá que hacer frente a las etiquetas anidadas OR; estos son instrucciones de consulta soportados en CAML

CAML.NET le puede ayudar en su búsqueda.

Otros consejos

Para aquellos que utilizan Sharepoint 2010, hay un elemento disponible en:

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

Aquí hay 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>");

FullTextSqlQuery

Es posible buscar MOSS utilizando sentencias SQL, utilizando el FullTextSqlQuery clase. No tengo ninguna experiencia del uso de esta clase personalmente. Estos artículos pueden ser de utilidad:

YACAMLQT

Por otra parte, existe también (otra herramienta de consulta CAML) YACAMLQT que le permite crear SharePoint CAML consultas utilizando una sintaxis de T-SQL.

LINQ to SharePoint

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

U2U CAML Query Builder

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

U2U CAML Query Builder para SharePoint en la acción
(fuente: u2u.net )

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 utilizado en la comunidad de SharePoint.

Tenga en cuenta, si usted está construyendo las consultas CAML en código, entonces le recomiendo que eche un vistazo a la CAML .NET proyecto en CodePlex , que ofrece " un conjunto de lenguaje basado en .NET herramientas para la creación de componentes de consulta CAML dinámicos y reutilizables ".

I enfrentado una cosa similar y al final tuvo que crear un algoritmo recursivo para generar el anidado o estructura. Aquí está mi algoritmo

var DynamicQuery = '<Query><Where>{{DYNAMICSTRING}}</Where></Query>';
var OneOR = '<Or><Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq>{{DYNAMICSTRING}}</Or>';
var TwoOr = '<Or><Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq><Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq></Or>';
var OnlyEq =  '<Eq><FieldRef Name="IMEI" /><Value Type="Text">{{SearchValue}}</Value></Eq>';
function generateAdvancedInQuery(x){
    if(x.length == 1)
        return OnlyEq.replace('{{SearchValue}}',x[0]);
    else if(x.length == 2)
        return TwoOr.replace('{{SearchValue}}',x[0]).replace('{{SearchValue}}',x[1]);
    else 
        return OneOR.replace('{{SearchValue}}',x[x.length-1]).replace('{{DYNAMICSTRING}}',generateAdvancedInQuery(x.splice(0,x.length-1) ) );   
}

x = ['438753234098792','438753234098793','438753234098794','438753234098795','438753234098796','438753234098797','438753234098798'];

var Caml = DynamicQuery.replace('{{DYNAMICSTRING}}',generateAdvancedInQuery(x) )

Esto genera la consulta caml XML como

<Query>
    <Where>
        <Or>
            <Eq>
                <FieldRef Name="IMEI" />
                <Value Type="Text">438753234098798</Value>
            </Eq>
            <Or>
                <Eq>
                    <FieldRef Name="IMEI" />
                    <Value Type="Text">438753234098797</Value>
                </Eq>
                <Or>
                    <Eq>
                        <FieldRef Name="IMEI" />
                        <Value Type="Text">438753234098796</Value>
                    </Eq>
                    <Or>
                        <Eq>
                            <FieldRef Name="IMEI" />
                            <Value Type="Text">438753234098795</Value>
                        </Eq>
                        <Or>
                            <Eq>
                                <FieldRef Name="IMEI" />
                                <Value Type="Text">438753234098794</Value>
                            </Eq>
                            <Or>
                                <Eq>
                                    <FieldRef Name="IMEI" />
                                    <Value Type="Text">438753234098792</Value>
                                </Eq>
                                <Eq>
                                    <FieldRef Name="IMEI" />
                                    <Value Type="Text">438753234098793</Value>
                                </Eq>
                            </Or>
                        </Or>
                    </Or>
                </Or>
            </Or>
        </Or>
    </Where>
</Query>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top