lunes, 8 de junio de 2026

LINQ: operaciones comunes

Continuamos con esta serie sobre LINQ y la lectura de archivos XML y JSON. Ahora profundizaremos un poco con las operaciones básicas que podemos realizar:

  • Where: Filtrar. 
  • Select: Proyecta campos. 
  • OrderBy: Ordenar. 
  • GroupBy: Agrupar y contar. 
  • Join: Unir colecciones. 
  • Any: Comprobar existencia. 
  • All: Comprobar condición en todos. 
  • Count: Devolver cantidad.

Consultas en archivos XML con LINQ

Realizaremos algunas consultas teniendo como entrada el siguiente archivo XML:

empleados.xml

<?xml version="1.0" encoding="UTF-8"?>
<Empleados>
<Empleado> 
<Id>4392552</Id>
<Nombre>Horacio</Nombre>
<Apellidos>Gomez Torres</Apellidos>
<Correo>horacio.gomez.tor@infotec.com</Correo>
<Salario>25000.00</Salario>
<Departamento>202</Departamento>
</Empleado>

<Empleado>
<Id>4292856</Id>
<Nombre>Veronica</Nombre>
<Apellidos>Uribe Gomora</Apellidos>
<Correo>veronica.uribe.gom@infotec.com</Correo>
<Salario>30000.00</Salario>
<Departamento>204</Departamento>
</Empleado>


<Empleado>
<Id>4701330</Id>
<Nombre>Karla</Nombre>
<Apellidos>Perez Perez</Apellidos>
<Correo>karla.perez.per@infotec.com</Correo>
<Salario>28000.00</Salario>
<Departamento>200</Departamento>
</Empleado>

<Empleado>
<Id>4701366</Id>
<Nombre>Juan</Nombre>
<Apellidos>Archundia Lara</Apellidos>
<Correo>juan.archundia.lar@infotec.com</Correo>
<Salario>38000.00</Salario>
<Departamento>204</Departamento>
</Empleado>

</Empleados>

Mapearemos las etiquetas XML en una clase C#.

Empleado.cs

using System.Xml.Serialization;

namespace model
{
    public class Empleado
    {
        public string Id { get; set; } = string.Empty;
        public string Nombre { get; set; } = string.Empty;
        public string Apellidos { get; set; } = string.Empty;
        public string Correo { get; set; } = string.Empty;
        public decimal Salario { get; set; } = decimal.Zero;
        public string Departamento { get; set; } = string.Empty;
    }

    [XmlRoot("Empleados")]
    public class Empleados
    {
        [XmlElement("Empleado")]
        public List<Empleado> Lista { get; set; }
    }
}

En una entrega anterior vimos cómo consultar documentos XML.

El siguiente bloque es importante para serializar los datos a partir de un documento XML.

// Ruta del archivo XML
 public static readonly string PATH_XML = "empleados.xml";

// Serializar datos
var serializer = new XmlSerializer(typeof(Empleados));

// Lectura del XML
using var reader = new StreamReader(PATH_XML);

Comenzaremos con la operación Where:

          Console.WriteLine("Empleados mejor pagados:");
             var empleadosBienPagados = from emp in empleados.Lista
                               where emp.Salario > 28000
                               select emp;
            foreach (var emp in empleadosBienPagados)
            {
                Console.WriteLine($"{emp.Nombre} - {emp.Salario}");
            }

En SQL sería:

SELECT *
FROM empleados
WHERE Salario > 28000;

Continuamos con la operación Select:

           Console.WriteLine("Nombre y correo:");
            var contactosDev = from dev in empleados.Lista
                   select new { dev.Nombre, dev.Correo };

            foreach (var emp in contactosDev)
            {
                Console.WriteLine($"{emp.Nombre} - {emp.Correo}");
            }

En SQL sería:

SELECT Nombre, Correo
FROM empleados;

Continuamos con la operación OrderBy:

           Console.WriteLine("Empleados [por salario ascendente]:");
            var empleadosOrdenados = from emp in empleados.Lista
                         orderby emp.Salario
                         select emp;
            foreach (var emp in empleadosOrdenados)
            {
                Console.WriteLine($"{emp.Nombre} {emp.Apellidos}, Depto: {emp.Departamento} , Salario: {emp.Salario}");
            }

En SQL sería:

SELECT Nombre, Apellidos, Departamento, Salario
FROM empleados
ORDER BY Salario ASC;

Continuamos con la operación GroupBy y Count:

             Console.WriteLine("Agrupar empleados por departamento:");
            var empleadosPorDepto = from emp in empleados.Lista
                        group emp by emp.Departamento into deptGroup
                        select new
                        {
                            Departamento = deptGroup.Key,
                            Cantidad = deptGroup.Count()
                        };
            foreach (var emp in empleadosPorDepto)
            {
                Console.WriteLine($"Departamento: {emp.Departamento} , Cantidad: {emp.Cantidad}");
            }

En SQL sería:

SELECT Departamento, COUNT(*) AS Cantidad
FROM empleados
GROUP BY Departamento;

Para el conteo (COUNT) sería:

SELECT COUNT(*) AS TotalEmpleados
FROM empleados;

Continuamos con la operación Any:

bool hayAltosSueldos = empleados.Lista.Any(e => e.Salario > 30000);
            if(hayAltosSueldos)
            {
                Console.WriteLine("Existe al menos un empleado con un salario relativamente grande.");
            }

En SQL sería:

SELECT CASE 
         WHEN EXISTS (SELECT 1 FROM empleados WHERE Salario > 30000) 
         THEN 'TRUE' 
         ELSE 'FALSE' 
       END AS HayAltosSueldos;

Finalizamos con la operación All:

bool todosConCorreoEdu = empleados.Lista.All(d => d.Correo.EndsWith("infotec.com"));
            if(todosConCorreoEdu)
            {
                Console.WriteLine("Todos los empleados tienen correo institucional.");
            }

En SQL sería:

SELECT CASE 
         WHEN NOT EXISTS (
              SELECT 1 FROM empleados 
              WHERE Correo NOT LIKE '%infotec.com'
         )
         THEN 'TRUE'
         ELSE 'FALSE'
       END AS TodosConCorreoInstitucional;

Programa completo:

Program.cs

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Xml.Linq;
using model;
using System.Xml.Serialization;

class Program
{
    public static readonly string PATH_XML = "empleados.xml";
    
    static void Main()
    {
        var serializer = new XmlSerializer(typeof(Empleados));
        using var reader = new StreamReader(PATH_XML);
        Empleados empleados = (Empleados)serializer.Deserialize(reader);
        if(empleados != null)
        {
             Console.WriteLine("Empleados mejor pagados:");
             var empleadosBienPagados = from emp in empleados.Lista
                               where emp.Salario > 28000
                               select emp;
            foreach (var emp in empleadosBienPagados)
            {
                Console.WriteLine($"{emp.Nombre} - {emp.Salario}");
            }

            Console.WriteLine("Nombre y correo:");
            var contactosDev = from dev in empleados.Lista
                   select new { dev.Nombre, dev.Correo };

            foreach (var emp in contactosDev)
            {
                Console.WriteLine($"{emp.Nombre} - {emp.Correo}");
            }

            Console.WriteLine("Empleados [por salario ascendente]:");
            var empleadosOrdenados = from emp in empleados.Lista
                         orderby emp.Salario
                         select emp;
            foreach (var emp in empleadosOrdenados)
            {
                Console.WriteLine($"{emp.Nombre} {emp.Apellidos}, Depto: {emp.Departamento} , Salario: {emp.Salario}");
            }

            Console.WriteLine("Agrupar empleados por departamento:");
            var empleadosPorDepto = from emp in empleados.Lista
                        group emp by emp.Departamento into deptGroup
                        select new
                        {
                            Departamento = deptGroup.Key,
                            Cantidad = deptGroup.Count()
                        };
            foreach (var emp in empleadosPorDepto)
            {
                Console.WriteLine($"Departamento: {emp.Departamento} , Cantidad: {emp.Cantidad}");
            }


            bool hayAltosSueldos = empleados.Lista.Any(e => e.Salario > 30000);
            if(hayAltosSueldos)
            {
                Console.WriteLine("Existe al menos un empleado con un salario relativamente grande.");
            }

            bool todosConCorreoEdu = empleados.Lista.All(d => d.Correo.EndsWith("infotec.com"));
            if(todosConCorreoEdu)
            {
                Console.WriteLine("Todos los empleados tienen correo institucional.");
            }

        }

        

    }
}

Construimos y ejecutamos:

$ dotnet build
$ dotnet run

Salida:

Empleados mejor pagados:
Veronica - 30000.00
Juan - 38000.00
Nombre y correo:
Horacio - horacio.gomez.tor@infotec.com
Veronica - veronica.uribe.gom@infotec.com
Karla - karla.perez.per@infotec.com
Juan - juan.archundia.lar@infotec.com
Empleados [por salario ascendente]:
Horacio Gomez Torres, Depto: 202 , Salario: 25000.00
Karla Perez Perez, Depto: 200 , Salario: 28000.00
Veronica Uribe Gomora, Depto: 204 , Salario: 30000.00
Juan Archundia Lara, Depto: 204 , Salario: 38000.00
Agrupar empleados por departamento:
Departamento: 202 , Cantidad: 1
Departamento: 204 , Cantidad: 2
Departamento: 200 , Cantidad: 1
Existe al menos un empleado con un salario relativamente grande.
Todos los empleados tienen correo institucional.

¡Hemos creado consultas básicas con LINQ!

Continuaremos con esta serie sobre C# y LINQ.

Enlaces:

https://codemonkeyjunior.blogspot.com/2026/06/linq-consultando-documentos-json.html
https://codemonkeyjunior.blogspot.com/2025/12/linq-consultando-documentos-xml.html
https://codemonkeyjunior.blogspot.com/2025/11/linq-un-lenguaje-de-consulta-para-c.html

No hay comentarios:

Publicar un comentario

LINQ: operaciones comunes

Continuamos con esta serie sobre LINQ y la lectura de archivos XML y JSON . Ahora profundizaremos un poco con las operaciones básicas ...

Etiquetas

Archivo del blog