Linq, un lenguaje de consultas que marca diferencias

Language Integrated Query es un lenguaje de consultas creado para facilitar la explotación de los datos sin importar el tipo de fuente de datos utilizada. Permite consultar información en tecnologías tan diferentes como ficheros XML, bases de datos relacionales o colecciones fuertemente tipadas.

Para ello el “truco” está crear una capa que permita tratar los datos con un lenguaje orientado a objetos y que se abstraiga de la fuente de datos subyacente. De esta forma el desarrollador se puede centrar en la lógica de la consulta olvidándose de la sintaxis específica de cada fuente de datos.

Veamos unos cuantos ejemplos.

Creando la estructura


La forma más simple que nos podemos encontrar al hacer consultas linq es realizar las query contra un colección tipada, que sea iqueryable. En este ejemplo vamos a realizar primero la carga de los datos en una lista y después vamos a realizar varios tipos de selección.

Voy a utilizar un proyecto asp.net, en C# y con webform. Y lo primero es construir la estructura que voy a utilizar para almacenar los datos


public struct persona
{
    public string nombre { get; set; }
    public string apellido { get; set; }
    public int edad { get; set; }
}

A continuación construyo la clase que me va a crear y llenar de datos una colección IQueryable, que será a la que le realice las consultas Linq.


public class constructorDeListados
{ public static IQueryable construyeListadoDePersonas() { List personas = new List();

    personas.Add(new persona { nombre = “Juan”, apellido = “Perez”, edad = 30 });
    personas.Add(new persona { nombre = “Pedro”, apellido = “Gutierrez”, edad = 21 });
    personas.Add(new persona { nombre = “Maria”, apellido = “Perez”, edad = 45 });

    return personas.AsQueryable();
}

}

Lanzando consultas


Ahora sí, me voy a la clase principal de la página, y en el método On_Load añado las diferentes consultas. Como por ejemplo el seleccionar el primer registro que su nombre sea igual a Juan.


IQueryable personas = constructorDeListados.construyeListadoDePersonas();

       persona juan = (from registro in personas
                        where registro.nombre == “Juan”
                        select registro).FirstOrDefault();

Aquí solo destacar dos cosas:

  • La similitud de sintaxis a una consulta SQL.

  • La diferencia de utilizar el select al final.

Pero la legilibilidad está asegurada y se entiende perfectamente que es lo que está buscando la consulta. Es importante el tener un soporte de intellisense completo tanto en la sintaxis de la consulta como en los objetos implicados en ella.

Si en vez de traerme un solo objeto del tipo persona, me traigo una colección, tengo dos opciones. O declararlo de forma completa en el tipo de la variable que recoge el resultado o utilizar otra facilidad del framework, que son los tipos implícitos. Y que se declaran del tipo var.


var losPerez = from registro in personas
               where registro.apellido == "Perez"
               select registro;

Aquí obtendríamos una colección con dos objetos persona. Uno por cada uno de los que tuvieran el apellido Perez. Y aquí podemos darle una pequeña vuelta a la tuerca y decirle que, además, me los traiga ordenados por su edad.


var losPerez = from registro in personas
               where registro.apellido == "Perez"
               orderby (registro.edad)
               select registro;

Es más, este resultado lo puedo utilizar, a su vez, para seguir tratando la información. Por ejemplo buscar seleccionar dentro de los Perez, aquellos cuyo nombre contenga una cadena específica,


var MarPerez = from registro in losPerez
              where registro.nombre.Contains("Mar")
              select registro;

Para ir acabando, todo lo que estoy haciendo con una sintaxis “estandar”, lo puedo hacer por las tan maravillosas como peligrosas expresiones lambdas. Para traer un ejemplo, de esta forma se escribiría la búsqueda del primer objeto cuyo nombre sea Pedro,


persona Pedro = personas.Select(ob => ob).Where(ob => ob.nombre == "Pedro").FirstOrDefault();

Como una primera y breve aproximación a esta tecnología de consultas, creo que ha estado bien. La documentación y la literatura es muy amplia y variada. Teniendo en cuenta que solo estamos rascando en la superficie, que los métodos en linq son muchos, que se pueden utilizar expresiones lambda, que se integra de forma perfecta con el ORM Entities Framework y que es plenamente extensible; podemos decir sin duda que aquí hay para estudiar un rato largo.

Otra cosa que no he de olvidar, es que el número de proovedores no para de crecer. Además del mencionado XML y sql server, existen proveedores para aplicar linq en php, en JavaScript, o en Twiter (si sobre los resultados de las consultas a las API).

P.D. Estos ejemplos que he traído son perfectos para practicar desarrollo con TDD, aunque entonces crearía toda la estructura en un fichero del tipo clase, para que el MSTest no nos construya esos test terribles de los fichero aspx.cs.

Más información | MSDN, Aprendiendo LINQ para Visual Basic 2008 by Jorge Serrano
En GenbetaDev | Conociendo los métodos de extensión. Fundamentos de LINQ I, La potencia de Linq sobre JavaScript

Portada de Genbeta