Ir al contenido principal

Linq y Tipos Anónimos

En este post quiero platicar de tres características del .NET Framework disponibles desde su versión 3.5 allá por el año 2007:

  1. Linq
  2. LinqToEntities
  3. Tipos anónimos
Linq

Son métodos de extensión que nos permite realizar consultas, filtrado y muchas otras funcionalidades bastante parecido a como lo haríamos haciendo consultas sql en un manejador de bases de datos, incluso la sintáxis es bastante parecida.

LinqToEntities

Fue desarrollado para interactuar con Entity Framework, que sirve para interactuar de manera estandarizada con diferentes motores de bases de datos, en el que existe una clase de contexto y usándola podemos hacer consultas complejas al manejador de base de datos de manera simple usando código .NET.

Tipos Anónimos

A diferencia de los tipos dinámicos, son tipos estáticos fuertemente tipados que se validan en tiempo de compilación que nos permite crear objetos que no están basados en una clase, pero que nos ofrece una funcionalidad bastante útil a la hora de trabajar con linq.

Veamos 5 Ejemplos en los que intentamos ejemplificar los conceptos antes mencionados.



Definición de Entidades

internal class TiposImágenes
{
    public int Clave { get; set; }

    public string Descripción { get; set; }
}

internal class Imagen
{
    public int Clave { get; set; }

    public int TipoImagen { get; set; }

    public string Ruta { get; set; }

    public string Nombre { get; set; }
}

Llenado de Listas de Ejemplo

private static List<TiposImágenes> CargarTiposImágenes()
{
    List<TiposImágenes> tiposImágenes = new List<TiposImágenes>();
    tiposImágenes.Add(new TiposImágenes() {
        Clave = 1,
        Descripción = "Documento de Identidad"
    });
    tiposImágenes.Add(new TiposImágenes() {
        Clave = 2,
        Descripción = "Comprobante de Domicilio"
    });
    tiposImágenes.Add(new TiposImágenes() {
        Clave = 3,
        Descripción = "Comprobante de Ingresos" 
    });
    return tiposImágenes;
}

private static List<Imagen> CargarImágenes()
{
    List<Imagen> imágenes = new List<Imagen>();
    imágenes.Add(new Imagen() {
        Clave = 1,
        TipoImagen = 1,
        Ruta = "C:\\Imágenes",
        Nombre = "Imagen1.jpg"
    });
    imágenes.Add(new Imagen() {
        Clave = 2,
        TipoImagen = 2,
        Ruta = "C:\\Imágenes",
        Nombre = "Imagen2.jpg" 
    });
    imágenes.Add(new Imagen() {
        Clave = 3,
        TipoImagen = 2,
        Ruta = "C:\\Imágenes",
        Nombre = "Imagen3.jpg"
    });
    imágenes.Add(new Imagen() {
        Clave = 4,
        TipoImagen = 3,
        Ruta = "C:\\Imágenes",
        Nombre = "Imagen4.jpg"
    });
    imágenes.Add(new Imagen() {
        Clave = 5,
        TipoImagen = 3,
        Ruta = "C:\\Imágenes",
        Nombre = "Imagen5.jpg"
    });
    imágenes.Add(new Imagen() {
        Clave = 6,
        TipoImagen = 3,
        Ruta = "C:\\Imágenes",
        Nombre = "Imagen6.jpg"
    });
    return imágenes;
}

Ejemplo # 1. Imágenes en Carpeta 1

List<Imagen> filtrada = imágenes.Where(i => i.TipoImagen.Equals(1)).ToList();
foreach (Imagen imagen in filtrada)
{
    Console.WriteLine("{0} {1}", imagen.Clave, imagen.Nombre);
}

Ejemplo # 2. Imágenes en Carpetas 1 y 2

var imágenesFiltradas = imágenes.Where(i => i.TipoImagen.Equals(1) || i.TipoImagen.Equals(2)).
Select(i => new{
    TipoDocumento = tiposImágenes.
        Where(ti => ti.Clave.Equals(i.TipoImagen)).FirstOrDefault().Descripción,
    Imagen = Path.Combine(i.Ruta, i.Nombre)
});
foreach (var imagen in imágenesFiltradas)
{
    Console.WriteLine("Tipo de Documento: {0}, Imagen: {1}",
        imagen.TipoDocumento, imagen.Imagen);
}

Ejemplo # 3. Imágenes en Carpetas 2 y 3

int[] tiposImágenesFiltrar = new int[] { 2, 3 };
imágenesFiltradas = imágenes.Where(i => tiposImágenesFiltrar.Contains(i.TipoImagen)).
Select(i => new
{
    TipoDocumento = tiposImágenes.
        Where(ti => ti.Clave.Equals(i.TipoImagen)).FirstOrDefault().Descripción,
    Imagen = Path.Combine(i.Ruta, i.Nombre)
});
foreach (var imagen in imágenesFiltradas)
{
    Console.WriteLine("Tipo de Documento: {0}, Imagen: {1}",
        imagen.TipoDocumento, imagen.Imagen);
}

Ejemplo # 4. Número de Imágenes Por Carpeta

var count = imágenes.GroupBy(i => i.TipoImagen).Select(i => new {
    key = tiposImágenes.Where(ti => ti.Clave.Equals(i.Key)).FirstOrDefault().Descripción,
    Count = i.Count()
});
foreach (var carpeta in count)
{
    Console.WriteLine("Carpeta: {0}, Cantidad de Imágenes: {1}", carpeta.key, carpeta.Count);
}

Ejemplo # 5. Imágenes Asociadas a Cada Carpeta

var groupBy = imágenes.GroupBy(i => i.TipoImagen).Select(i => new {
    key = tiposImágenes.Where(ti => ti.Clave.Equals(i.Key)).FirstOrDefault().Descripción,
    imágenes = i.Select(img => new {
        Clave = img.Clave,
        Imagen = Path.Combine(img.Ruta, img.Nombre)
    })
});
foreach (var carpeta in groupBy)
{
    Console.WriteLine("Carpeta: {0}", carpeta.key);
    foreach (var imagen in carpeta.imágenes)
    {
        Console.WriteLine("Clave: {0}, Imagen: {1}", imagen.Clave, imagen.Imagen);
    }
}

Aquí les dejo un link para que puedan revisar más acerca de la sintáxis de Linq: MSDN Linq

Y en este otro pueden descargar el proyecto realizado en Visual Studio 2013: Descarga Código Fuente

Comentarios

Entradas más populares de este blog

Publicación de WCF en Net.TCP

Una de las grandes características de WCF es la forma en como éstos pueden ser expuestos a nuestros clientes, por ejemplo los siguientes protocolos, de manera muy recurrente: Http TCP Net Pipe ¿Sabes en que casos usar cada uno? Http cuando el servicio y el cliente se encuentran en redes diferentes TCP cuando el servicio y el cliente se encuentran en la misma red, pero en equipos diferentes Net Pipe cuando el servicio y el cliente se encuentran alojados en el mismo equipo ¿Por qué razón? Por cuestiones de redimiento y seguridad de la información Si una petición http toma un tiempo de 200 ms, por poner un ejemplo Una petición tcp tomará aproximadamente el 20% menos que la petición http (40 ms aproximadamente) Y una petición Net Pipe , tomará aproximadamente el 80% del tiempo que toma el hacer una petición tcp (32 ms aproximadamente) Para mayor entendimiento, chequen este post que alguna vez consultamos para entender un poco más acerca de éstos conceptos: https://j...

Validación de Fechas con jQuery Validator

Al validar fechas con jQuery Validate nos encontramos con el problema de que dicha validación se hace en formato: MM/DD/YYYY, esto es correcto, pero no tanto para formato de fechas de México al menos que es más común para nosotros hacerlo de manera que dicho formato sea: DD/MM/YYYY. Para poder solucionar este problema haremos algunas modificaciones en las librerías: jquery.validate.js jquery.validate.min.js Veamos el siguiente video para la implementación de dicha solución: jquery.validate.js Se deja comentado el cómo se hace la validación original y se adiciona el código personalizado que permite validar el formato de fecha del tipo: DD/MM/YYYY 1 2 3 4 5 6 7 8 9 10 11 // http://jqueryvalidation.org/date-method/ // Nivisix Soluciones: personalización para formato de fechas DD/MM/YYYY date : function ( value, element ) { //return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); var com...

Predicados Dinámicos Linq Usando LinqKit

El escenario es el siguiente: Generar predicados linq dinámicos de acuerdo a un conjunto de parámetros variables. Ejemplo: Si tengo un listado de elementos, por ejemplo, los libros disponibles en una biblioteca y quiero hacer el filtrado de la misma usando uno o más parámetros de búsqueda. Se puede resolver usando predicados linq dinámicos. Supongamos que nuestra base de datos de libros está formada por una tabla llamada Libros con los siguientes campos: ISBN o identificado único Título del libro Precio Obviamente nuestra tabla puede estar conformada por más campos, dependiendo de las necesidades del negocio, para nuestro ejemplo, estos datos serán suficientes. El tipo de búsquedas que me gustaría realizar en el listado serían las siguientes: El título contenga alguna frase ingresada por el usuario Que el precio sea mayor al especificado por el usuario Que el precio sea menor al especificado por el usuario Que el precio se encuentre entre un rango mínimo y máximo ...