LINQ To SharePoint o LINQ4SP: Disponible la RC1!

Por fin, después de unos meses en lo que poco se ha sabido sobre la evolución de esta extensión de LINQ específicamente pensada para realizar consultas contra elementos de SharePoint, tenemos disponible la primera release candidate (RC1) de LINQ To SharePoint (LINQ4SP). Podéis descargaros LINQ4SP de este enlace.

image

Aparte de la noticia de la RC1 de LINQ4SP, creo que también es destacable que esta extensión de LINQ para SharePoint no esté incluida en el proyecto original de Codeplex, lo que creo que va en la dirección de que la versión final de LINQ4SP será de pago…veremos que pasa en el futuro. En cualquier caso, esta RC1 es una excelente oportunidad de probar las prestaciones de LINQ4SP.

SharePoint y LINQ (I)!

Recientemente en uno de los proyectos en los que estamos trabajando surgió la necesidad de consultar datos de una lista de SharePoint y mostrarlos ordenados en base a uno de los campos de la misma. La primera alternativa en la que pensamos para solventar esta necesidad fue la de CAML, pero entre medias también pensamos que LINQ era otra opción interesante. La primeras preguntas que nos surgieron aquí fueron ¿cómo está la integración de SharePoint y LINQ?, ¿puedo consultar datos de una lista de SharePoint mediante LINQ? La respuesta a al primera pregunta es que “más o menos”, mientras que la respuesta a la segunda es que sí…y ahora os explicaré los motivos de estas respuestas. A la hora de consultar datos de SharePoint, tenemos dos alternativas:

  • Usar LINQ To SharePoint, que es una extensión de LINQ que traduce consultas LINQ a consultas CAML en SharePoint. El problema de esta extensión es que parece que está descontinuada, puesto que desde la versión alfa de noviembre de 2008 no ha habido nuevas versiones.
  • Aprovecharnos la potencia que nos la clase List<T> que nos permitirá construir un objeto consultable mediante LINQ a partir de los elementos de una lista de SharePoint (que  no es consultable mediante LINQ).

En este post os voy a mostrar el segundo punto y como superar algunas limitaciones a trabajar con objetos de tipo List<SPListItem>. Lo pasos iniciales que he seguido son los siguientes:

  • Añadir unos datos de prueba a una lista tipo Links de SharePoint.
  • Crear un proyecto de aplicación de consola de Visual Studio 2008.
  • Añadir la referencia a Windows SharePoint Services 3.0.
image image image
  • En el código de la aplicación de consola, añadiremos las referencias necesarias para poder utilizar objetos de SharePoint por un lado, así como colecciones genéricas por otro.

//Espacios de nombres necesarios

using Microsoft.SharePoint;

using System.Collections.Generic;

  • A continuación añadimos el código necesario para poder realizar la consulta a la lista de SharePoint:
    • Creamos una instancia de un objeto SPSite a partir de la url de nuestro sitio SharePoint.
    • A partir del objeto SPSite, creamos una instancia de un objeto SPWeb.
    • A partir del objeto SPWeb, creamos una instancia de un objeto SPList especificando además que sea la lista Links.
    • Definimos un objeto de tipo List<SPListItem> que si permite consultas con LINQ.
    • Añadimos elementos al objeto List<SPListItem> recorriéndonos la lista origen.
    • Realizamos una consulta LINQ.
    • Mostramos el resultado ejecutando la consulta con un foreach (recordar que LINQ aplica evaluación diferida de consultas).

            //Acceso al sitio de SharePoint

            SPSite spsSite = new SPSite(“http://win-amr7ey1djky/&#8221;);

            SPWeb spwWeb = spsSite.OpenWeb();

            SPList splList = spwWeb.Lists[“Links”];

 

            //Construimos un objeto que se pueda consultar con LONQ           

            List<SPListItem> lItems = new List<SPListItem>();

            foreach (SPListItem splItem in splList.Items)

            {

                lItems.Add(splItem);

            }

 

            //Consulta LINQ

            var LinqQuery = from l in lItems

                            orderby l.Title

                            select l;

 

            //Visualizamos los resultados

            Console.WriteLine(“***************Resultado Consulta LINQ # 1***************”);

            foreach (var l in LinqQuery)

            {

                Console.WriteLine(l.Name);

 

            }         

 

            Console.ReadLine();

  • Sin más, mostramos el resultado:

image

Pero, no todo es tan bonito como parece…si os fijáis en el código, únicamente estoy mostrando la propiedad Name de la lista. ¿Se pueden mostrar más propiedades de la lista? La respuesta es que sí, pero no todas…esto lo he podido comprobar gracias al intellisense de Visual Studio. Por ejemplo, para esta lista no se muestra información como el usuario creador del ítem, la fecha de modificación, etc.

image

Entonces, ¿mi gozo en un pozo? La respuesta es que sí y que no…sí, porque no tengo accesibles todas las propiedades de manera indirecta, pero no porque si las tengo accesibles indirectamente gracias a que el objeto que almacena el resultado de la consulta LINQ ofrece una propiedad Xml en la que tenemos todos los campos de la lista de SharePoint…absolutamente todos. El código para comprobarlo es el siguiente:

            Console.WriteLine(“***************Resultado Consulta LINQ # 2***************”);

            foreach (var l in LinqQuery)

            {

                Console.WriteLine(l.Xml);

 

            }

            Console.ReadLine();

Y el resultado que se visualiza por pantalla es:

image

Por lo tanto, tengo toda la información de cada ítem de la lista…en formato Xml, pero esto es tratable…con lo que lo tengo todo. Y hasta aquí llega este post sobre SharePoint y LINQ. Espero que os haya resultado interesante.

ADO.NET Entity Framework y LINQ To SQL: Ejemplos de las novedades del SP1 Beta 1!

Poco a poco empiezan a aparecer ejemplos de algunos de los cambios que vienen con el SP1 Beta 1 de .NET Framework 3.5. En esta ocasión, os dejo algunos recursos interesantes sobre el tema:

VLINQ: Diseñador de consultas para LINQ To SQL!

Si hace unos meses hablábamos de una útil e imprescindible herramienta para probar nuestras consultas LINQ como es LINQPad, hace un rato me he encontrado otro diseñador de consultas específico para LINQ To SQL, pero que se diferencia de LINQPad en qué se trata de un diseñador que se integra con Visual Studio 2008 como un Add-In más y que nos ayuda en el diseño de dichas consultas. Se trata del proyecto VLINQ, que durante 6 meses fue desarrollado y liderado por un equipo de desarrollo francés en colaboración con Microsoft. Os podéis descargar VLINQ de este enlace.

CIIN & Nuberos.NET: LINQ & ADO.NET Entity Framework!

Después del retorno y primer evento de Nuberos.Net en 2008 (sobre Silverlight y en el que José María Cuesta nos contó las posibilidades de Silverlight y surgieron discusiones interesantes sobre las otras grandes opciones que hay en el mercado: SVG y Flex), estamos que no paramos y ya tenemos en marcha el evento correspondiente a este mes de marzo: LINQ & ADO.NET Entity Framework. Aquí van los detalles del evento:

Evento_LINQ_Nuberos

Conoce LINQ, el nuevo framework que habilita la definición de consultas integradas en el lenguaje y permite crear querys contra objetos de memoria, bases de datos relacionales, documentos XML, y otros elementos. Haremos un recorrido práctico de las principales características y novedades de este nuevo lenguaje que vendrá con la nueva versión de Visual Studio, y que se apoya en las innovaciones de lenguaje introducidas en las nuevas versiones de C# (3.0) y VB (9.0). Veremos alguno de los sabores de LINQ como: LINQ To Objects, LINQ To SQL o LINQ To Entities…y completaremos el evento con la nueva revolución tecnológica en el acceso a datos en plataforma .NET: ADO.NET Entity Framework. Ven con nosotros y preparate para la gran revolución: Are you ready?

Datos de interés:

  • Audiencia: Desarrolladores, Jefe de Proyecto

  • Requistos previos: Conocimientos del entorno Visual Studio 2005 / Visual Studio 2008 

  • Fecha: Jueves, 27 de marzo

  • Hora:  19:00 a 21:00

  • Precio: gratuito

  • Ponente: Juan Carlos González Martín (Centro de Innovación en Integración, CIIN). 

  • Lugar:

AGENCIA DE DESARROLLO LOCAL DE SANTANDER – Servicio de Promoción de Empresas y Autoempleo

Bajos del Mercado de México

c/ Alta 133

39008  Santander  CANTABRIA

España

Más información y registro al evento en este enlace.

Extensibilidad de LINQ: LINQ Flavours!

Como sabéis, una de las grandes novedades de Visual Studio 2008 y de .NET Framework 3.5 es el Language Integrated Query (LINQ) que habilita la definición de consultas integradas en el lenguaje de programación y es una de las piedras angulares de las nuevas versiones de C# y VB. Precisamente, muchas de las innovaciones que se han introducido en estas nuevas versiones son la base de LINQ, y el resumen de las mismas es el siguiente:

image 

Ahora bien, además de apoyarse en estas innovaciones, LINQ define un modelo ampliable y extensible para definir nuestras propias consultas o API’s de consulta, de manera que podemos ir más allá de las extensiones para LINQ que por defecto vienen con Visual Studio 2008, .NET Framework 3.5 y ADO.NET Entity Framework:

image
  • LINQ To Objects y LINQ To XML para trabajar con fuentes de datos no relacionales.
  • Para ADO.NET tenemos:
    • LINQ To Datasets
    • LINQ To SQL
    • LINQ To Entities

Tras esta pequeña introducción, la idea de este post es hacer una recopilación y recorrido por las extensiones que para LINQ se han ido creando durante los últimos dos años, algunos de los cuales presentó Octavio Hernández en su charla dentro del lanzamiento de Visual Studio 2008, SQL Server 2008 y Windows Server 2008 (me hubiera gustado estar en el evento y asistir a esta charla).. Empecemos.

Proveedores de LINQ Personalizados

Como comentábamos, LINQ es un modelo completamente extensible y aquí están algunas de las extensiones que he ido descubriendo cuando he preparado seminarios de LINQ, en los propios cursos de LINQ,…

IEnumerable<T> data = …;
var q = from x in data.AsParallel() where p(x) orderby k(x) select f(x);
foreach (var e in q) a(e);
  • CLINQ (que no es Continuous LINQ, proyecto en Codeplex que he descubierto esta tarde…), en este caso nos referimos al proyecto CLINQ que Tomas Petricek, MVP de C#, inició para que el lenguaje C++ tuviese soporte para LINQ (de hecho, cualquier lenguaje que soporte la CLS puede añadir sus propias implementaciones de LINQ). Por ejemplo, mediante las extensiones desarrolladas por Tomas para C++, la consulta a una BD en C++ quedaría:
// create connection to database 
NorthwindData db(".. connection string .."); 

// declare database query 
Expr<Customers^> cvar = Var<Customers^>("c"); 
CQuery<String^>^ q = db.QCustomers 
  ->Where(clq::fun(cvar, cvar.City == "London")) 
  ->Select(clq::fun(cvar, 
      cvar.ContactName + Expr<String^>(", ") + cvar.CompanyName)); 

// execute query and output results 
for each(String^ s in q->Query) 
  Console::WriteLine(s);

Tomas ha creado una sección en Codeplex dedicada a extensiones para LINQ. De momento está incluido CLINQ, pero según el autor, poco a poco irá añadiendo alguna más.

  • LINQ To SharePoint, como no podía ser de otro modo, existe desde hace tiempo un proveedor de LINQ específicamente pensado para realizar consultas contra listas de SharePoint usando sintaxis LINQ. Esta extensión tiene su sección correspondiente en Codeplex, y además de habilitar consultas LINQ, dispone de una herramienta de creación de clases sobre las que definir consultas a partir de listas de SharePoint: SpMetal (misma idea que el SQLMetal de LINQ To SQL). Actualmente en Codeplex tenemos disponble la versión v0.2.4.0 alfa preparada para .NET Framework 3.5 y Visual Studio 2008. Un ejemplo de uso de esta extensión es el siguiente:
var ctx = new SharePointDataContext(new Uri(http://fileserver));
ctx.Credentials = new NetworkCredential(“dimitri”,”LinqToSharePoint”);

var books = ctx.GetList<Books>();

var res = from b in books
select new { b.Title, b.Author};

foreach (var u in res)
Console.WriteLine(u);

  • LINQ To Amazon, en este caso se trata de una extensión creada por uno de los autores del libro LINQ in Action, Fabrice Marguerie, que permite consultar libros de Amazon mediane LINQ. De hecho, esta extensión permite consultas LINQ contra un cierto catálogo de libros, obteniendo las estructuras XML que devuelven los servicios web de Amazon. Un ejemplo de uso de esta extensión sería el siguiente:
var query =
  from book in new Amazon.BookSearch()
  where
    book.Title.Contains(“ajax”) &&
    (book.Publisher == “Manning”) &&
    (book.Price <= 25) &&
    (book.Condition == BookCondition.New)
  select book;

var sequence = query.ToSequence();

  •  LINQ To NHibernate, esta extensión permite escribir consultas LINQ que son posteriormente traducidas a Criteria Queries que son ejecutadas por un objeto de Sesión NHibernate. Todo el código de este proyecto está accesible en este enlace…y aunque un poco fuera de tópico, fijaros en la sorpresa que os encontraréis si entráis en la página principal Hooked on LINQ: LINQ Reference Stuff…pero fijaros en el formato ;) :
Image Image

        Desde luego, las tazas son “molonas”, creo que me las voy a pedir por esto y porque merece la pena darle soporte a Hooked on LINQ. Están realizando un excelente trabajo.

  • DbLINQ Project, se trata de un proyecto en Code2Code en el que podéis encontrar las bases de un proveedor LINQ para bases de datos Oracle, MySQL y PostgreSQL. Como se comenta en la página del proyecto DbLINQ, se garantiza que las consultas simples funcionarán sin problemas, aunque no las complejas…precisamente la disponibilidad del código habilita que los desarrolladores puedan testear bien estas extensiones y evaluar, extender y corregir el comportamiento del proveedor al modelar consultas complejas. Las releases del código están en este enlace. Todo el proyecto se está desarrollando bajo licencia MIT para ser compatible con el proyecto Mono.
  • LINQ To LDAP, se trata de un proveedor capaz de enviar consultas LINQ a un directorio activo sobre LDAP partiendo de las expresiones de filtrado en LDAP que aparecen en la RFC 2254. Un ejemplo de uso de este proveedor creado por Bart de Smet’s es el siguiente:
var users = new DirectoryObject<User>(new DirectoryEntry(“LDAP://localhost”), SearchScope.Subtree);
var groups = new DirectoryObject<Group>(new DirectoryEntry(“LDAP://localhost”), SearchScope.Subtree);
var res1 = from usr in users select usr;
Console.WriteLine(“QUERY 1n=======”);
foreach (var w in res1)
     Console.WriteLine(“{0}: {1} {2}”, w.Name, w.Description, w.PasswordLastSet);
     Console.WriteLine();
var res2 = from usr in users where usr.Name == “A*” select usr;
Console.WriteLine(“QUERY 2n=======”);
foreach (var w in res2)
    Console.WriteLine(“{0}’s full name is {1}”, w.Name, w.Dn);
    Console.WriteLine();
  • LINQ To TFS, esta nueva extensión creada por Octavio Hernández,y de la que tuve conocimiento a raíz del post de Octavio, la podemos encontrar en Codeplex y se trata de un proveedor de LINQ preparado para consultar el repositorio de Team Foundation Server en el que se hace el almacenamiento y control de versiones de Work Items.
  • LINQ To Flickr, esta extensión al estilo de LINQ To Amazon permite consultar fotografías de Flickr por tag, fecha de creación, identificador de usuario o título. El autor de esta extensión es el egipcio

    Mohammed Hossam El-Din.

  • LINQ To JSON, se trata de una extensión para JSon.NET que permite crear y consultar objetos JSON mediante consultas de LINQ. Su creador es James Newton, y esta extensión permite trabajar con objetos JSON de manera similar a como LINQ To XML permite manipular estructuras XML.
JObject o = JObject.FromObject(new

{

  channel = new

  {

    title = “James Newton-King”,

    link = “http://james.newtonking.com&#8221;,

    description = “James Newton-King’s blog.”,

    item = from p in posts orderby p.Title

         select new

        {

          title = p.Title,

          description = p.Description,

          link = p.Link,

          category = p.Categories

        }

  }

});

  • BLINQ, en este caso no se trata de una extensión en sí, sino de una herramienta (descontinuada) que permite generar sitios ASP.NET para visualizar, crear y manipular datos obtenidos mediante LINQ a partir de un cierto esquema relacional.

Y como podéis ver en este recopilatorio Hosam Kamel, el listado completo de proveedores de LINQ que podemos encontrar en la red es este:

  • LINQ to Amazon.
  • LINQ to Active Directory.
  • LINQ to Bindable Sources (SyncLINQ).
  • LINQ to CRM.
  • LINQ to Geo – Language Integrated Query for Geospatial Data.
  • LINQ to Excel
  • LINQ to Expressions (MetaLinq).
  • LINQ to Flickr.
  • LINQ to Google.
  • LINQ to Indexes (LINQ and i40).
  • LINQ to IQueryable.
  • LINQ to JSON.
  • LINQ to LDAP.
  • LINQ to NHibernate.
  • LINQ to JavaScript.
  • LINQ to Lucene.
  • LINQ to Metaweb(freebase).
  • LINQ to MySQL, Oracle and PostgreSql (DdLINQ project).
  • LINQ to RDF Files.
  • LINQ to Sharepoint.
  • LINQ to SimpleDB.
  • LINQ to Streams.
  • LINQ to WebQueries.
  • LINQ to WMI.
  • LINQ to XtraGrid.

Está claro que el título del post de Hosam, LINQ To Everything, es muy apropiado.

Creación de proveedores de LINQ personalizados

Además de las extensiones comentadas, cualquier desarrollador puede crear las suyas propias. De hecho, estos son algunos ejemplos que muestran como habría que proceder:

  • Escribir un proveedor personalizado desde cero: en esta entrada tenéis un ejemplo.
  • Escribir proveedores personalizados partiendo del proyecto LINQExtender de Codeplex. El ejemplo en este caso está aquí.

Nota: Ambos ejemplos han sido realizados por Mehfuz Hossain.

…¿y existe LINQ fuera de la plataforma Microsoft? Buena pregunta, y la respuesta es que sí. De hecho, en el mundo Java ya ha aparecido LINQ for Java o Quaere. Como se comenta en este post, Quaere is a DSL que añade sintaxis de consultas tipo SQL en el desarrollo de aplicaciones Java basándose en el modelo del proyecto LINQ ;)…como muestra, un pequeño ejemplo de Quaere:

Integer[] numbersA = {0, 2, 4, 5, 6, 8, 9}; Integer[] numbersB = {1, 3, 5, 7, 8}; Iterable<Variant> pairs =    from("a").in(numbersA).from("b").in(numbersB).where(lt("a", "b")). select(create(property("a"),property("b"));

Sin más, hasta aquí llega este post en el que he intentado reflejar la extensibilidad de LINQ. Espero que os haya resultado interesante.