Anda di halaman 1dari 14

Qu es LINQ?

Language-Integrated Query (LINQ) es un conjunto de caractersticas en Visual Studio 2008 que agrega eficaces capacidades de consulta a la sintaxis de los lenguajes C# y Visual Basic. LINQ incluye patrones estndar y de fcil aprendizaje para consultar y actualizar datos, y su tecnologa se puede extender para utilizar potencialmente cualquier tipo de almacn de datos. Visual Studio 2008 incluye ensamblados de proveedores para LINQ que habilitan el uso de LINQ con colecciones de .NET Framework, bases de datos de SQL Server, conjuntos de datos de ADO.NET y documentos XML. Language-Integrated Query (LINQ) es una importante innovacin en Visual Studio 2008 y .NET Framework versin 3.5 que elimina la distancia que separa el mundo de los objetos y el mundo de los datos. Tradicionalmente, las consultas con datos se expresan como cadenas sencillas, sin comprobacin de tipos en tiempo de compilacin ni compatibilidad con IntelliSense. Adems, es necesario aprender un lenguaje de consultas diferente para cada tipo de origen de datos: bases de datos SQL, documentos XML, servicios web diversos, etc. LINQ convierte una consulta en una construccin de lenguaje de primera clase en C# y Visual Basic. Las consultas se escriben para colecciones de objetos con establecimiento inflexible de tipos, utilizando palabras clave del lenguaje y operadores con los que se est familiarizado. La ilustracin siguiente muestra una consulta LINQ parcialmente completada en una base de datos de SQL Server en C#, con comprobacin de tipos completa y compatibilidad con IntelliSense.

En Visual Studio se pueden escribir consultas LINQ en Visual Basic o en C# con bases de datos de SQL Server, documentos XML, conjuntos de datos ADO.NET y cualquier coleccin de objetos que admita IEnumerable o la interfaz genrica IEnumerable<T>. Tambin se ha previsto la compatibilidad de LINQ con el marco de entidades ADO.NET, y otros fabricantes se

encuentran escribiendo proveedores LINQ para muchos servicios web y otras implementaciones de base de datos. Puede utilizar consultas LINQ en proyectos nuevos o junto a consultas que no son LINQ en proyectos existentes. El nico requisito es que el proyecto est orientado a la versin 3.5 de .NET Framework.

Consultas con LINQ

Introduccin
Una consulta es una expresin que recupera datos de un origen de datos. Las consultas normalmente se expresan en un lenguaje de consultas especializado. A lo largo del tiempo se han ido desarrollando lenguajes diferentes para los distintos tipos de orgenes de datos, como SQL para las bases de datos relacionales y XQuery para XML. Por consiguiente, los programadores han tenido que aprender un nuevo lenguaje de consultas para cada tipo de formato u origen de datos que deben admitir. LINQ simplifica esta situacin, proporcionando un modelo coherente para trabajar con datos de distintos tipos de formatos y orgenes de datos. En una consulta LINQ, siempre se trabaja con objetos. Se utilizan los mismos modelos de codificacin bsicos para consultar y transformar datos de documentos XML, bases de datos SQL, conjuntos de datos ADO.NET, colecciones .NET y cualquier otro formato para el que haya disponible un proveedor LINQ.

Las tres partes de una operacin de consulta


Todas las operaciones de consulta LINQ se componen de tres acciones distintas:
1. Obtencin del origen de datos. 2. Creacin de la consulta. 3. Ejecucin de la consulta.

En el ejemplo siguiente se muestra cmo se expresan las tres partes de una operacin de consulta en el cdigo fuente. En el ejemplo se utiliza por comodidad una matriz de enteros como origen de datos, pero los mismos conceptos se aplican a otros orgenes de datos. En el resto del tema se hace referencia a este ejemplo.

En la siguiente ilustracin se muestra la operacin de consulta completa. En LINQ, la ejecucin de la consulta es distinta de la propia consulta; en otras palabras, no se recuperan datos con la simple creacin de la variable de consulta.

El origen de datos
En el ejemplo anterior, como el origen de datos es una matriz, se admite implcitamente la interfaz genrica IEnumerable<(T>. Este hecho implica que se puede consultar con LINQ. Una consulta se ejecuta en una instruccin foreach y foreach requiere IEnumerable o IEnumerable<T>.
NotaLos tipos que admiten IEnumerable<T> o una interfaz derivada, como la genrica IQueryable<T>, se conocen como tipos consultables.

Un tipo que se puede consultar no requiere ninguna modificacin o tratamiento especial para servir como origen de datos LINQ. Si los datos de origen an no estn en memoria como tipo que se puede consultar, el proveedor LINQ debe representarlos como tales. Por ejemplo, LINQ to XML carga un documento XML en un tipo XElement que se puede consultar: XElement contacts = XElement.Load(@"c:\myContactList.xml"); Con LINQ to SQL, primero se crea una asignacin relacional de objetos en tiempo de diseo, ya sea manualmente o mediante el Diseador relacional de objetos (Diseador R/O). Despus, se escriben las consultas en los objetos y, en tiempo de ejecucin, LINQ to SQL controla la comunicacin con la base de datos. En el ejemplo siguiente, Customer representa una tabla concreta de la base de datos y Table<Customer> admite la interfaz genrica IQueryable<T>, que se deriva de IEnumerable<T>. La consulta cuando es ejecutada, devolver una secuencia de objetos Customer cuyos tipos son inferidos por el compilador. El tipo del resultado de la consulta, IQueryable<T>, se compila en un arbol de expresiones el cual es convertido en tiempo de ejecucin en una consulta SQL.

Para crear tipos de orgenes de datos especficos, la regla bsica es muy simple: un origen de datos LINQ es cualquier objeto que admite la interfaz genrica IEnumerable o una interfaz que herede de ella.
NotaTambin se pueden utilizar tipos como ArrayList, que admite la interfaz no genrica IEnumerable, como origen de datos LINQ.

La consulta

La consulta especifica qu informacin se va a recuperar de uno o varios orgenes de datos. Opcionalmente, una consulta tambin especifica cmo debera ordenarse, agruparse y darse forma a esa informacin antes de ser devuelta. Una consulta se almacena en una variable de consulta y se inicializa con una expresin de consulta. Para simplificar la escritura de consultas, C# incluye nueva sintaxis de consulta. La consulta del ejemplo de la matriz de nmeros anterior devuelve todos los nmeros pares de la matriz de enteros. La expresin de consulta contiene tres clusulas: from, where y select. (Si est familiarizado con SQL, habr observado que el orden de las clusulas se invierte respecto al orden de SQL.) La clusula from especifica el origen de datos, la clusula where aplica el filtro y la clusula select especifica el tipo de los elementos devueltos. Aqu, lo importante es que, en LINQ, la propia variable de consulta no realiza ninguna accin ni devuelve datos. Simplemente almacena la informacin necesaria para generar los resultados cuando la consulta se ejecute posteriormente.

Ejecucin de la consulta
Ejecucin diferida

Como se ha mencionado previamente, la variable de consulta slo almacena los comandos de la consulta. La ejecucin real de la consulta se aplaza hasta que se procese una iteracin en la variable de consulta, en una instruccin foreach. Este concepto se conoce como ejecucin diferida. La instruccin foreach es tambin donde se recuperan los resultados de la consulta. Por ejemplo, en la consulta anterior, la variable de iteracin num contiene cada valor (de uno en uno) en la secuencia devuelta. Dado que la propia variable de consulta nunca contiene los resultados de la consulta, se puede ejecutar tantas veces como se desee. Por ejemplo, puede que una aplicacin independiente actualice continuamente una base de datos. En su aplicacin, podra crear una consulta que recuperase los datos ms recientes, y podra ejecutarla repetidamente cada cierto tiempo para recuperar cada vez resultados diferentes.
Forzar la ejecucin inmediata

Las consultas que realizan funciones de agregacin en un intervalo de elementos de origen primero deben recorrer en iteracin dichos elementos. Algunos ejemplos de esas consultas son Count, Max, Average y First. Se ejecutan sin una instruccin foreach explcita porque la propia consulta debe utilizar foreach para devolver un resultado. Debe saber tambin que estos tipos de consultas devuelven un solo valor, no una coleccin IEnumerable. La consulta siguiente devuelve un recuento de los nmeros pares de la matriz de origen:

Para forzar la ejecucin inmediata de cualquier consulta y almacenar en memoria cach sus resultados, puede llamar al mtodo ToList<TSource> o ToArray<<TSource>. Tambin puede forzar la ejecucin si coloca el bucle foreach justo despus de la expresin de consulta. Sin embargo, al llamar a ToList o ToArray tambin se almacenan en memoria cach todos los datos en un objeto de coleccin nico.

LINQ y tipos genricos

Introduccin
Las consultas LINQ se basan en tipos genricos, que se incluyeron por primera vez en la versin 2.0 de .NET Framework. No se requieren conocimientos avanzados de los tipos genricos para poder empezar a escribir consultas.
1. Al crear una instancia de una clase de coleccin genrica, como List<T>, la "T" se reemplaza con el tipo de objetos que contendr la lista. Por ejemplo, una lista de cadenas se expresa como List<string> y una lista de objetos Customer se expresa como List<Customer>. Una lista genrica tiene establecimiento inflexible de tipos y proporciona muchas ventajas frente a las colecciones que almacenan sus elementos como Object. Si intenta agregar Customer a List<string>, obtendr un error en tiempo de compilacin. Es fcil utilizar las colecciones genricas, porque no es necesario realizar conversiones de tipos en tiempo de ejecucin. 2. IEnumerable<T> es la interfaz que permite enumerar las clases de coleccin genricas mediante la instruccin foreach. Las clases de coleccin genricas admiten IEnumerable<T> de la misma forma que las clases de coleccin no genricas, como ArrayList, admiten IEnumerable.

Variables IEnumerable en consultas LINQ


Las variables de consulta LINQ tienen tipos IEnumerable<T> o un tipo derivado, como IQueryable<T>. Cuando se encuentre una variable de consulta de tipo IEnumerable<Customer>, slo significa que la consulta, cuando se ejecute, generar una secuencia de cero o ms objetos Customer.

Permitir al compilador administrar las declaraciones de tipos genricos


Si lo prefiere, puede evitar la sintaxis genrica con el uso de la palabra clave var. La palabra clave var indica al compilador que deduzca el tipo de una variable de consulta examinando el origen de datos especificado en la clusula from. En el ejemplo siguiente vemos el uso de la palabra clave var. Se genera el mismo cdigo compilado en ambos casos:

La palabra clave var es til cuando el tipo de la variable es obvio o cuando no es tan importante especificar explcitamente los tipos genricos anidados, como los que se generan en las consultas de grupo. Por lo general, si utiliza var, debe saber que puede dificultar la legibilidad del cdigo para los dems.

Operaciones bsicas de consulta (LINQ)

Introduccin
En este tema se ofrece una breve introduccin a las expresiones de consulta LINQ y algunas de las clases de operaciones tpicas que se realizan en una consulta.

Obtener un origen de datos


En una consulta LINQ, el primer paso es especificar el origen de datos. En C#, como en la mayora de los lenguajes de programacin, se debe declarar una variable antes de poder utilizarla. En una consulta LINQ, la clusula from aparece en primer lugar para introducir el origen de datos (customers) y la variable de rango (cust).

La variable de rango es como la variable de iteracin en un bucle foreach, con la diferencia de que en una expresin de consulta realmente no se produce ninguna iteracin. Cuando se ejecuta la consulta, la variable de rango acta como referencia para cada elemento sucesivo de customers. Dado que el compilador puede deducir el tipo de cust, no tiene que especificarlo explcitamente. Una clusula let puede introducir variables de rango adicionales.

Filtrar
Probablemente la operacin de consulta ms comn es aplicar un filtro en forma de expresin booleana. El filtro hace que la consulta devuelva slo los elementos para los que la expresin es verdadera. El resultado se genera mediante la clusula where. El filtro aplicado especifica qu elementos se deben excluir de la secuencia de origen. En el ejemplo siguiente, slo se devuelven los customers cuya direccin se encuentra en Londres (London).

Puede utilizar los operadores lgicos AND y OR de C#, con los que ya estar familiarizado, para aplicar las expresiones de filtro que sean necesarias en la clusula where. Los siguientes ejemplos muestran la clausula where para: Devolver slo los clientes con direccin en "London" AND cuyo nombre sea "Devon" Devolver los clientes con direccin en Londres o Pars

Ordenacin

A menudo es necesario ordenar los datos devueltos. La clusula orderby har que los elementos de la secuencia devuelta se ordenen segn el comparador predeterminado del tipo que se va a ordenar. La consulta anterior se puede extender para ordenar los resultados segn la propiedad Name. Dado que Name es una cadena, el comparador predeterminado realiza una ordenacin alfabtica de la A a la Z. Para ordenar los resultados en orden inverso, de la Z a la A, utilice la clusula orderby descending.

Grupo
La clusula group permite agrupar los resultados segn la clave que se especifique. Por ejemplo, podra especificar que los resultados se agrupen por City para que todos los clientes de London o Pars estn en grupos individuales. En este caso, la clave es cust.City.

Al finalizar una consulta con una clusula group, los resultados adoptan la forma de una lista de listas. Cada elemento de la lista es un objeto que tiene un miembro Key y una lista de elementos agrupados bajo esa clave. Al procesar una iteracin en una consulta que genera una secuencia de grupos, debe utilizar un bucle foreach anidado. El bucle exterior recorre en iteracin cada grupo y el bucle interior recorre en iteracin los miembros de cada grupo. Si debe hacer referencia a los resultados de una operacin de grupo, puede utilizar la palabra clave into para crear un identificador con el que se puedan realizar ms consultas. La consulta siguiente devuelve slo los grupos que contienen ms de dos clientes:

Combinacin
Las operaciones de combinacin crean asociaciones entre las secuencias que no se modelan explcitamente en los orgenes de datos. Por ejemplo, puede realizar una operacin de combinacin para buscar todos los clientes con direccin en Londres que realicen pedidos de productos a proveedores de Pars. En LINQ, la clusula join funciona siempre con colecciones de objetos, en lugar de con tablas de base de datos directamente. En LINQ no es necesario utilizar join tan a menudo como en SQL, porque las claves externas en LINQ se representan en el modelo de objetos como propiedades que contienen una coleccin de elementos. Por ejemplo, un objeto Customer contiene una coleccin de objetos Order. En lugar de realizar una combinacin, se tiene acceso a los pedidos utilizando la notacin de punto:
from order in Customer.Orders

Seleccin (proyecciones)
La clusula select genera resultados de consulta y especifica la "forma" o el tipo de cada elemento devuelto. Por ejemplo, puede especificar si sus resultados estarn compuestos de objetos Customer completos, un solo miembro, un subconjunto de miembros o algn tipo de resultado completamente diferente basado en un clculo o en un objeto nuevo. Cuando la clusula select genera algo distinto de una copia del elemento de origen, la operacin se denomina proyeccin. El uso de proyecciones para transformar los datos es una eficaz funcionalidad de las expresiones de consulta LINQ.

Transformaciones de datos con LINQ

Introduccin
Language-Integrated Query (LINQ) no trata simplemente de la recuperacin de datos. Tambin es una herramienta eficaz para transformarlos. Mediante una consulta LINQ, puede utilizar una secuencia de origen como entrada y modificarla de muchas maneras para crear una nueva secuencia de salida. Puede modificar la propia secuencia sin modificar los elementos con operaciones de ordenacin y agrupacin. Sin embargo, la caracterstica ms eficaz de las consultas LINQ quizs sea la posibilidad de crear nuevos tipos. Esto se logra en la clusula select. Por ejemplo, puede realizar las tareas siguientes:
Combinar varias secuencias de entrada en una sola secuencia de salida que tiene un tipo nuevo. Crear secuencias de salida cuyos elementos estn formados por una o varias propiedades de cada elemento de la secuencia de origen.

Crear secuencias de salida cuyos elementos estn formados por los resultados de operaciones realizadas en los datos de origen. Crear secuencias de salida en un formato diferente. Por ejemplo, puede transformar datos de filas SQL o archivos de texto en XML.

stos son slo algunos ejemplos. De hecho, estas transformaciones se pueden combinar de varias maneras en la misma consulta. Adems, la secuencia de salida de una consulta se puede utilizar como secuencia de entrada para una nueva consulta.

Combinar varias entradas en una sola secuencia de salida


Puede utilizar una consulta LINQ para crear una secuencia de salida que contenga elementos de ms de una secuencia de entrada. En el ejemplo siguiente se muestra cmo combinar dos estructuras de datos en memoria, pero se pueden aplicar los mismos principios para combinar datos de orgenes XML, SQL o de conjunto de datos. Supongamos que tenemos los dos tipos de clases siguientes:

En el ejemplo siguiente se muestra la consulta:

Seleccionar un subconjunto de cada elemento de origen


Principalmente existen dos maneras de seleccionar un subconjunto de cada elemento de la secuencia de origen:
1. Para seleccionar un solo miembro del elemento de origen, utilice la operacin con punto.

En el ejemplo siguiente, supongamos que un objeto Customer contiene varias propiedades pblicas que incluyen una cadena denominada City. Cuando se ejecuta, esta consulta generar una secuencia de salida de cadenas.
var query = from cust in Customers select cust.City;

1. Para crear elementos que contienen ms de una propiedad del elemento de origen, puede

utilizar un inicializador de objeto con un objeto con nombre o un tipo annimo. En el ejemplo siguiente se muestra el uso de un tipo annimo para encapsular dos propiedades de cada elemento Customer:
var query = from cust in Customer select new {Name = cust.Name, City = cust.City};

Transformar objetos en memoria en XML


Las consultas LINQ hacen que sea fcil transformar los datos entre estructuras de datos en memoria, bases de datos SQL, conjuntos de datos ADO.NET y documentos o secuencias XML. En el ejemplo siguiente se transforman los objetos de una estructura de datos en memoria en elementos XML.

El cdigo genera el siguiente resultado XML:


< Root> <student> <First>Svetlana</First> <Last>Omelchenko</Last> <Scores>97,92,81,60</Scores> </student> <student> <First>Claire</First> <Last>O'Donnell</Last> <Scores>75,84,91,39</Scores> </student> <student> <First>Sven</First> <Last>Mortensen</Last> <Scores>88,94,65,91</Scores> </student> </Root>

Realizar operaciones con elementos de origen


Es posible que una secuencia de salida no contenga elementos o propiedades de elemento de la secuencia de origen. Por el contrario, la salida podra ser una secuencia de valores que se calcula utilizando los elementos de origen como argumentos de entrada. Cuando se ejecuta la siguiente consulta simple, genera una secuencia de cadenas cuyos valores representan un clculo basado en la secuencia de origen de elementos de tipo double.

Anda mungkin juga menyukai