Linq, creando un where dinámico

En este turorial vamos a ver como construir un where de manera dinámica.

Rodríguez Patiño, Eduardo
6,666 lecturas
Rodríguez Patiño, Eduardo
Hemos migrado hace poco nuestras publicaciones del blog antiguo. Si crees que esta se encuentra incompleta o sin coherencia deja un comentario para restaurarla manualmente.

Es muy común querer hacer un where dinámico para mostrar información en base al criterio del usuario, pues bien buscando bastante y sin éxito llegue a la solución por mi cuenta la cual fue muy sencilla y la quiero comartir contigo:

Primero hagamos un ejemplo práctico, tenemos la clase Usuario con sus atributos y contiene un método que nos devolvera una lista de Usuarios, la cual podremos filtrar dicha lista en base a los parametros que le enviemos. Analizemos el código:

class Usuario 
    {
        public int id { get; set; }
        public string Nombre { get; set; }
        public string Apellido { get; set; }
        public int Edad { get; set; }

        public static dynamic Listar(int edad = 0, string Nombre = null)
        {
            var usuarios = new List<Usuario>()
            {
                new Usuario{ id = 1, Nombre = "Pamela", Apellido = "Villanueva", Edad = 24},
                new Usuario{ id = 2, Nombre = "Carla", Apellido = "Rodriguez", Edad = 30},
                new Usuario{ id = 3, Nombre = "Ana", Apellido = "Perez", Edad = 25},
                new Usuario{ id = 4, Nombre = "Sandra", Apellido = "Gonzales", Edad = 17},
                new Usuario{ id = 5, Nombre = "Rosa", Apellido = "Patiño", Edad = 40}
            };

            var _filtrado = usuarios.Where(x => x.id > 0);

            // Si queremos filtrar por la edad
            if(edad > 0)
            {
                _filtrado = _filtrado.Where( x => x.Edad == edad);
            }

            // Si queremos decirle que el nombre comience o coincida con
            if(Nombre != null)
            {
                _filtrado = _filtrado.Where(x => x.Nombre.StartsWith(Nombre));
            }

            return _filtrado.ToList<Usuario>();
        }

Que es lo que hago, básicamente tengo una lista del objeto Usuario y lo primero que hago es un WHERE algo tonto, diciendole que el ID siempre se mayor, en nuestro caso en la base de datos podemos decirle que el ID sea IS NOT NULL, cosa que sabemos que nunca va a pasar pero el objetivo de este es que nos retorne el objeto que crea el predicado de LinQ, por eso lo guardo en la variable _filtrado ya que a ese objeto le vamos a sumar diferentes condiciones.

Entendido esto, es por eso esa manera hago una condición en base a nuestra regla de negocio, en mi caso le digo si la edad es mayor a 0 le sumo un WHERE indicándole que la edad debe ser mayor a 0. El mismo principio uso para el nombre, la ídea es ir sumando los predicados a nuestra variable _filtrado.

Al final hago un retorno diciendo que se convierta en una lista del tipo Usuario.

¿Como hago el filtro?

Como nuestro método Listar recibe parametros opcionales podemos hacer lo siguiente:

  • var usuarios = Usuario.Listar(); // Me devolvera todo los usuarios
  • var usuarios = Usuario.Listar(30); // Aquellos usuarios que tengan 30 años
  • var usuarios = Usuario.Listar(0, "Car"); // Aquellos usuarios que su nombre comience con 'Car%'
¿Te gustó nuestra publicación?
Suscríbete a nuestro boletín