Saltar al contenido

Filtrar/Buscar usando múltiples campos – ASP.NET MVC

Por fin luego de mucho luchar hemos hallado la contestación de este dilema que algunos los lectores de nuestro sitio presentan. Si tienes algún detalle que compartir no dejes de dejar tu conocimiento.

Solución:

Le recomiendo que separe las preocupaciones y utilice un enfoque en el que el código de su controlador sea así, simple, hermoso y extensible:

public ActionResult Index(ProductSearchModel searchModel)

    var business = new ProductBusinessLogic();
    var model = business.GetProducts(searchModel);
    return View(model);

Beneficios:

  • Puedes poner todo lo que necesites en tu ProductSearchModel basado en sus requisitos.
  • Puedes escribir cualquier lógica en GetProducts basado en requisitos. No hay limitación.
  • Si agrega un nuevo campo u opción para buscar, su acción y controlador permanecerán intactos.
  • Si la lógica de su búsqueda cambia, su acción y controlador permanecerán intactos.
  • Puede reutilizar la lógica de búsqueda siempre que necesite buscar en productos, en controladores o incluso en otra lógica empresarial.
  • Tener tal ProductSearchModelpuedes usarlo como modelo de ProductSearch vista parcial y se puede aplicar DataAnnotations para mejorar la validación del modelo y ayudar a la interfaz de usuario a representarlo usando Display u otro attributes.
  • Puede agregar otra lógica empresarial relacionada con su producto en esa clase de lógica empresarial.
  • Siguiendo de esta manera podrás tener una aplicación más organizada.

Ejemplo de implementación:

Supongamos que tienes un Product clase:

public class Product

    public int Id  get; set; 
    public int Price  get; set; 
    public string Name  get; set; 

Puedes crear un ProductSearchModel clase y coloque algunos campos que desea buscar en función de ellos:

public class ProductSearchModel

    public int? Id  get; set; 
    public int? PriceFrom  get; set; 
    public int? PriceTo  get; set; 
    public string Name  get; set; 

Entonces puedes poner tu lógica de búsqueda en ProductBusinessLogic clase de esta manera:

public class ProductBusinessLogic

    private YourDbContext Context;
    public ProductBusinessLogic()
    
        Context = new YourDbContext();
    

    public IQueryable GetProducts(ProductSearchModel searchModel)
    
        var result = Context.Products.AsQueryable();
        if (searchModel != null)
        
            if (searchModel.Id.HasValue)
                result = result.Where(x => x.Id == searchModel.Id);
            if (!string.IsNullOrEmpty(searchModel.Name))
                result = result.Where(x => x.Name.Contains(searchModel.Name));
            if (searchModel.PriceFrom.HasValue)
                result = result.Where(x => x.Price >= searchModel.PriceFrom);
            if (searchModel.PriceTo.HasValue)
                result = result.Where(x => x.Price <= searchModel.PriceTo);
        
        return result;     
    

Entonces en tu ProductController puedes usar de esta manera:

public ActionResult Index(ProductSearchModel searchModel)

    var business = new ProductBusinessLogic();
    var model = business.GetProducts(searchModel);
    return View(model);

Nota IMPORTANTE:

En una implementación del mundo real, considere implementar un Dispose patrón para que su clase empresarial elimine el contexto de la base de datos cuando sea necesario. Para obtener más información, consulte Implementación de un método Dispose o Dispose Pattern.

Filtrado condicional

.ToList(), .First(), .Count() y algunos otros métodos ejecutan la consulta LINQ final. Pero antes de que se ejecute, puede aplicar filtros así:

var stocks = context.Stocks.AsQueryable();
if (batchNumber != null) stocks = stocks.Where(s => s.Number = batchNumber);
if (name != null)        stocks = stocks.Where(s => s.Name.StartsWith(name));
var result = stocks.ToList(); // execute query

Extensión WhereIf LINQ

Sencillo WhereIf puede simplificar significativamente el código:

var result = db.Stocks
    .WhereIf(batchNumber != null, s => s.Number == batchNumber)
    .WhereIf(name != null,        s => s.Name.StartsWith(name))       
    .ToList();

Implementación WhereIf. Es un método de extensión simple para IQueryable:

public static class CollectionExtensions

    public static IQueryable WhereIf(
        this IQueryable source,
        bool condition,
        Expression> predicate)
    
        if (condition)
            return source.Where(predicate);
        else
            return source;
    

Modo LINQ no WhereIf (recomendado)

WhereIf proporciona una forma más declarativa, si no desea usar extensiones, puede filtrar así:

var result = context.Stocks
    .Where(batchNumber == null || stock.Number == batchNumber)
    .Where(name == null || s => s.Name.StartsWith(name))
    .ToList();

Da exactamente el mismo efecto que WhereIf y funcionará más rápido ya que el tiempo de ejecución necesitará construir solo un ExpressionTree en lugar de construir varios árboles y fusionarlos.

Si estás de acuerdo, tienes la opción de dejar un enunciado acerca de qué le añadirías a este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *