LINQ Avanzado en C# (GroupBy, Join, Aggregate)
Aprende LINQ avanzado en C# con GroupBy, Join y Aggregate para realizar consultas complejas de datos.
LINQ no se limita al filtrado y ordenamiento básico.
Para un procesamiento de datos más complejo, ofrece operadores avanzados como GroupBy, Join y Aggregate.
En este artículo veremos cómo usar estos operadores con ejemplos.
GroupBy
GroupBy agrupa los elementos de una colección según una propiedad especificada.
Luego se pueden ejecutar consultas sobre estos grupos para obtener información estadística.
using System;
using System.Linq;
using System.Collections.Generic;
var estudiantes = new List<(string Nombre, string Ciudad)>
{
("Juan", "Madrid"),
("María", "Barcelona"),
("Miguel", "Madrid"),
("Sofía", "Barcelona"),
("David", "Valencia")
};
// Agrupar estudiantes por ciudad
var grupos = estudiantes.GroupBy(e => e.Ciudad);
foreach (var grupo in grupos)
{
Console.WriteLine($"Ciudad: {grupo.Key} - Cantidad de estudiantes: {grupo.Count()}");
foreach (var est in grupo)
Console.WriteLine($" {est.Nombre}");
}
// Salida:
// Ciudad: Madrid - Cantidad de estudiantes: 2
// Juan
// Miguel
// Ciudad: Barcelona - Cantidad de estudiantes: 2
// María
// Sofía
// Ciudad: Valencia - Cantidad de estudiantes: 1
// David
Join
Join funciona de manera similar a un INNER JOIN en SQL y permite combinar dos colecciones a partir de una clave común.
var estudiantes = new List<(int Id, string Nombre)>
{
(1, "Juan"),
(2, "María"),
(3, "Miguel")
};
var notas = new List<(int EstId, int Nota)>
{
(1, 90),
(2, 75),
(3, 82)
};
// Combinar estudiantes y notas con Join
var resultado = estudiantes.Join(
notas,
e => e.Id, // clave externa
n => n.EstId, // clave interna
(e, n) => new { e.Nombre, n.Nota }
);
foreach (var item in resultado)
Console.WriteLine($"{item.Nombre} → {item.Nota}");
// Salida:
// Juan → 90
// María → 75
// Miguel → 82
Aggregate
Aggregate realiza una operación acumulativa sobre una colección.
Funciona como un bucle, actualizando un valor acumulador hasta producir un resultado final.
var numeros = new List<int> { 2, 3, 4, 5 };
// Multiplicar todos los números
int producto = numeros.Aggregate((acc, n) => acc * n);
Console.WriteLine(producto); // 120
// Construir una cadena a partir de los números
string texto = numeros.Aggregate("Números:", (acc, n) => acc + " " + n);
Console.WriteLine(texto);
// Salida: Números: 2 3 4 5
Aplicación de ejemplo: Informe de ventas
En el siguiente ejemplo, los registros de ventas se procesan utilizando GroupBy, Join y Aggregate en conjunto.
public class Producto
{
public int Id { get; set; }
public string Nombre { get; set; } = string.Empty;
}
public class Venta
{
public int ProductoId { get; set; }
public int Cantidad { get; set; }
public decimal Precio { get; set; }
}
class Program
{
static void Main()
{
var productos = new List<Producto>
{
new Producto { Id = 1, Nombre = "Portátil" },
new Producto { Id = 2, Nombre = "Teléfono" },
new Producto { Id = 3, Nombre = "Tableta" }
};
var ventas = new List<Venta>
{
new Venta { ProductoId = 1, Cantidad = 2, Precio = 1000 },
new Venta { ProductoId = 2, Cantidad = 5, Precio = 500 },
new Venta { ProductoId = 1, Cantidad = 1, Precio = 950 },
new Venta { ProductoId = 3, Cantidad = 3, Precio = 300 }
};
// Combinar productos con ventas
var reporte = productos.Join(
ventas,
p => p.Id,
v => v.ProductoId,
(p, v) => new { p.Nombre, v.Cantidad, v.Precio }
);
// Agrupar por producto
var reporteAgrupado = reporte.GroupBy(r => r.Nombre);
foreach (var grupo in reporteAgrupado)
{
var ingresos = grupo.Aggregate(0m, (acc, r) => acc + (r.Cantidad * r.Precio));
Console.WriteLine($"{grupo.Key} → Ventas: {grupo.Count()}, Ingresos: {ingresos} EUR");
}
}
}
// Ejemplo de salida:
// Portátil → Ventas: 2, Ingresos: 2950 EUR
// Teléfono → Ventas: 1, Ingresos: 2500 EUR
// Tableta → Ventas: 1, Ingresos: 900 EUR
Resumen (TL;DR)
GroupBy: Agrupa elementos según una clave.Join: Combina dos colecciones a través de una clave común.Aggregate: Realiza una operación acumulativa para producir un único resultado.- Estos operadores son muy útiles para escenarios de informes y análisis de datos.