Consultas CAML para filtrar listas de SharePoint

Muy buenas a todos.

Hace bastante tiempo, cuando empecé con el blog, que coincidió además con mis inicios en SharePoint, escribí un artículo en el que hablaba sobre consultas con CAML. Con el tiempo, he visto que esta entrada es la que más visitas del blog recibe, y creo que en el fondo es muy escasa para conocer, siquiera por encima, lo que se puede hacer con CAML. Aprovechando también que ya conozco mucho más sobre esto, quiero escribir una entrada, con un contenido mucho más extenso sobre este tema.

Esta es la entrada del blog sobre CAML que escribí:

Consultas sobre CAML en Sharepoint 2010

Vamos a empezar por ver la estructura completa de una consulta en CAML y que partes la componen

<View>
 <Query>
      <OrderBy>
          ...
      </OrderBy>
      <Where>
         ...
      </Where>
 </Query>
 <ViewFields>
      <FieldRef Name='Title'/>
      <FieldRef Name='ID'/>
 </ViewFields>
 <RowLimit>10</RowLimit>
</View>

En una consulta CAML, tenemos las siguientes secciones:

  • Query: Que contiene los apartados OrderBy y Where de la consulta.
  • ViewFields: Es similar a la parte de Select de una consulta SQL. Nos permite indicar que campos queremos devolver en la consulta que vamos a realizar.
  • RowLimit: Indica el máximo número de columnas que puede devolver la consulta

¿Como podemos usar la clausula Where?

Voy a hacer un resumen ahora de algunas de las situaciones más comunes que se pueden dar cuando hacemos consultas CAML y queremos filtrar los elementos de una lista determinada.

Filtrando por un campo de la lista
<Where>
    <Eq>
        <FieldRef Name='Title' />
        <Value Type='Text'>ejemplo</Value>
    </Eq>
</Where>
<Where>
    <BeginsWith >
        <FieldRef Name='Title' />
        <Value Type='Text'>ejemplo</Value>
    </BeginsWith>
</Where>
<Where>
    <Contains>
        <FieldRef Name='Title' />
        <Value Type='Text'>ejemplo</Value>
    </Contains>
</Where>
Filtrando por campos de tipo Búsqueda
<Where>
    <Eq>
        <FieldRef Name='LookupField1' LookupId='TRUE'/>
        <Value Type='Lookup'>3</Value>
    </Eq>
</Where>
Filtrar un campo de tipo User
Filtrar usando la ID de un usuario cualquiera:

<Where>
  <Eq>
    <FieldRef Name="User1" LookupId="True" />
    <Value Type="User">123</Value>
  </Eq>
</Where>

Filtrar por el usuario actual:

<Where>
  <Eq>
    <FieldRef Name="User1" />
    <Value Type="Integer">
      <UserID />
    </Value>
  </Eq>
</Where>
Concatenando varios filtros
<Where>
    <And>
        <Eq>
            <FieldRef Name='LookupField1' LookupId='TRUE'/>
            <Value Type='Lookup'>3</Value>
        </Eq>
        <Eq>
            <FieldRef Name='TextField1'/>
            <Value Type='Text'>ejemplo</Value>
        </Eq>
    </And>
</Where>
<Where>
    <Or>
    <Eq>
        <FieldRef Name="User1" />
        <Value Type="Integer">
            <UserID />
        </Value>    
    </Eq>
    <And>
        <Eq>
            <FieldRef Name='LookupField1' LookupId='TRUE'/>
            <Value Type='Lookup'>3</Value>
        </Eq>
        <Eq>
            <FieldRef Name='TextField1'/>
            <Value Type='Text'>ejemplo</Value>
        </Eq>
    </And>
    </Or>
</Where>

Usando la clausula OrderBy

Esta clausula va dentro de Query al igual que Where y su uso es muy sencillo.

Ordenando de forma ascendente por un campo concreto
<OrderBy>
    <FieldRef Name='ID' />
</OrderBy>
Ordenando de forma descendente por un campo concreto
<OrderBy>
    <FieldRef Name='ID' Ascending='FALSE' />
</OrderBy>
Ordenando por varios campos una consulta
<OrderBy>
    <FieldRef Name='Field1' Ascending='False' />
    <FieldRef Name='Field2' />
</OrderBy>

Usando CAML dentro del modelo de objetos

El modelo de objetos nos proporciona una clase para hacer consultas CAML en nuestro código. Esta clase es la clase SPQuery. Vamos a ver como deberíamos usar en nuestro código esta clase

SPQuery consulta = new SPQuery();
consulta.Query="<Where><Eq><FieldRef Name="Field1" /><Value Type="Text">ejemplo</Value></Eq></Where>"

SPListItemCollection resultadoConsulta = lista.GetItems(consulta);

De esta forma podremos hacer un filtrado de la lista en cuestión que habremos cargado en la variable lista definida previamente. Algunas consideraciones sobre esta clase.

  • Si queremos añadir la clausula OrderBy, podemos hacerlo a través de la propiedad Query de la clase, junto con el Where
  • No incluir las etiquetas Query dentro de la propiedad Query de la clase, esto provocará que el resultado no sea el esperado
  • Si queremos limitar el número de resultados que nos devuelva la consulta, podemos hacerlo con la propiedad RowLimit de la clase. Además es una buena práctica limitar el número de resultados de la consulta, para tenerlo controlado en todo momento. Si no lo indicamos, por defecto (podéis comprobarlo con el depurador), el valor que se establece es muy grande y esto puede provocar problemas de rendimiento.
  • Podéis establecer una cadena con la estructura completa de una consulta CAML a través del campo ViewXml

Y esto es todo amigos, espero que os sea útil y sirva también para completar el artículo inicial sobre esta temática que escribí hace un tiempo.

Un saludo y buen fin de semana a todos

Anuncios