LINQ (Language INtegrated Query) nos permite escribir consultas (parecidas a consultas SQL) sobre nuestras colecciones (List, IEnumerable, …). Con estos operadores estándares, podremos hacer consultas determinando si existe un tipo de elemento o realizar una suma de la secuencia. Básicamente nos permite filtrar, enumerar y crear proyecciones de varios tipos de colecciones.
En LINQ tenemos un amplio conjunto de operadores. La siguiente tabla muestra los operadores de LINQ y una breve descripción de la funcionalidad que ofrecen.
Operador |
Descripción |
Agregación | |
Aggregate | Realiza un método personalizado sobre una secuencia |
Average | Calcula el promedio de una secuencia de valores numéricos |
Count | Devuelve el número de los elementos de una secuencia como un int |
LongCount | Devuelve el número de los elementos de una secuencia como un largo |
Min | Encuentra el número mínimo de una secuencia de números |
Max | Encuentra el número máximo de una secuencia de números |
Sum | Suma de los números en una secuencia |
Concatenación | |
Concat | Concatena dos secuencias en una secuencia |
Conversión | |
Cast | Convierte elementos de una secuencia en otro tipo dado |
OfType | Filtra los elementos de una secuencia de un determinado tipo |
ToArray | Devuelve un Array de una secuencia |
ToDictionary | Devuelve un Dictionary de una secuencia |
ToList | Devuelve un List de una secuencia |
ToLookup | Devuelve un Lookup de una secuencia |
ToSequence | Devuelve un IEnumerable de una secuencia |
Elemento | |
DefaultIfEmpty | Crea un elemento predeterminado para una secuencia vacía |
ElementAt | Devuelve el elemento de un índice determinado en una secuencia |
ElementAtOrDefault | Devuelve el elemento de un índice determinado en una secuencia o un valor predeterminado si el índice está fuera del intervalo |
First | Devuelve el primer elemento de una secuencia |
FirstOrDefault | Devuelve el primer elemento de una secuencia o un valor predeterminado si no se encuentra ningún elemento |
Last | Devuelve el último elemento de una secuencia |
LastOrDefault | Devuelve el último elemento de una secuencia o un valor predeterminado si no se encuentra ningún elemento |
Single | Devuelve el único elemento de una secuencia |
SingleOrDefault | Devuelve el único elemento de una secuencia o un valor predeterminado si no se encuentra ningún elemento |
Igualdad | |
SequenceEqual | Compara dos secuencias para ver si son equivalentes |
Generación | |
Empty | Genera una secuencia vacía |
Range | Genera una secuencia dado un rango |
Repeat | Genera una secuencia repitiendo un elemento un número determinado de veces |
Agrupación | |
GroupBy | Agrupa elementos de una secuencia por una agrupación dada |
Enlazando | |
GroupJoin | Realiza una combinación agrupada de dos secuencias |
Join | una combinación interna de dos secuencias |
Ordenación | |
OrderBy | Ordena una secuencia por valor (s) en orden ascendente |
OrderByDescending | Ordena una secuencia por valor (s) en orden de descendente |
ThenBy | Ordena una secuencia que ya se ha ordenado en orden ascendente |
ThenByDescending | Ordena una secuencia que ya se ha ordenado en orden descendente |
Reverse | Invierte el orden de los elementos de una secuencia |
Particionado | |
Skip | Devuelve una secuencia que omite un número determinado de elementos |
SkipWhile | Devuelve una secuencia que omite elementos que no cumplen una expresión |
Take | Devuelve una secuencia que toma un número determinado de elementos |
TakeWhile | Devuelve una secuencia que toma elementos que cumplen una expresión |
Proyección | |
Select | Crea una proyección a partir de una secuencia |
SelectMany | Crea una proyección One to Many de elementos de una secuencia |
Cuantificadores | |
All | Determina si todos los elementos de una secuencia cumplen una condición |
Any | Determina si los elementos de una secuencia cumplen una condición |
Contains | Determina si una secuencia contiene un elemento determinado |
Restricción | |
Where | Filtra los elementos de una secuencia |
Conjuntos | |
Distinct | Devuelve una secuencia sin elementos duplicados |
Except | Devuelve una secuencia que representa la diferencia entre dos secuencias |
Intersect | Devuelve una secuencia que representa la intersección de dos secuencias |
Union | Devuelve una secuencia que representa la unión de dos secuencias |
Vamos a ver algunos ejemplos de código:
Average
1: int[] nums = new int[] {1,2,3,4,5,6,7,8,9};
2: double avg = nums.Average();
Calculamos la media de los enteros del array.
Where
1: IEnumerable<Customer> customersInTenerife = customers.Where(c => c.City == "Tenerife");
Buscamos los clientes cuya ciudad sea Tenerife.
Take
1: IEnumerable<Product> MostExpensive10 =
2: products.OrderByDescending(p => p.UnitPrice).Take(10);
En este ejemplo, ordenamos los productos descendentemente por UnitPrice y luego
seleccionamos 10 productos.
Skip
1: IEnumerable<Product> AllButMostExpensive10 =
2: products.OrderByDescending(p => p.UnitPrice).Skip(10);
Aquí ordenamos, de nuevo, descendentemente por UnitPrice y seleccionamos todos los elementos menos los 10 más caros.
Join
1: var custOrders =
2: customers.Join(orders, c => c.CustomerID, o => o.CustomerID,
3: (c, o) => new { c.Name, o.OrderDate, o.Total }
4: );
Enlazamos los clientes con sus facturas y devolvemos una lista con el nombre del cliente, la fecha de la factura y el total facturado.
OrderBy/ThenBy
1: IEnumerable<Product> orderedProducts =
2: products.OrderBy(p => p.Category).
3: ThenByDescending(p => p.UnitPrice).
4: ThenBy(p => p.Name);
La siguiente consulta ordena la lista de productos por Category, luego por UnitPrice descendiente y por último por Name.
GroupBy
1: IEnumerable<IGrouping<string, Product>> productsByCategory =
2: products.GroupBy(p => p.Category);
Podemos agrupar los productos y obtener un IEnumerable agrupado que contenga la Category y los productos que corresponden a esa Category.
ToDictionary
1: Dictionary<int,Order> orders =
2: customers.SelectMany(c => c.Orders).
3: Where(o => o.OrderDate.Year == 2005).
4: ToDictionary(o => o.OrderID);
Creamos un Dictionary seleccionando las Facturas de los clientes del año 2005, utilizando como clave el OrderID.
Any
1: bool result = customers.Any(c => c.Name == "Pepe");
Devuelve True si encuentra algún cliente con el Name Pepe.
ForEach
1: List<customer> customers = GetCustomers();
2: customers.ForEach(p => Insertar(p));
Para cada cliente de la lista customers, ejecutamos el método Insertar pasándole por parámetro el elemento actual.
Si queremos más información sobre LINQ, lo mejor es pasarse por la MSDN y leernos la documentación o alguno de los tutoriales que tenemos sobre él.
Este es uno de los grandes avances que Microsoft incluyó con el Framework 3.5 y que nos facilita bastante la vida y nos permite programar mejor y más rápido.
Espero que disfrutéis tanto como yo escribiendo código y que lo hagáis más con LINQ, os lo recomiendo.
Saludos a todos…
Muy útil Alberto, thx.
Gran post!
Gracias
Gracias Alberto!!
Excelente, muchas gracias!