Filtrer / rechercher en utilisant plusieurs champs - ASP.NET MVC

j'utilise ASP.NET MVC CE 6.

j'ai une page de stock qui montre toutes les informations sur les articles de stock. Maintenant, je veux filtrer les enregistrements.

dans l'image ci-dessous j'ai 3 options. Je pourrais filtrer par chaque option, un à un ou par une combinaison de deux ou de trois.

je pensais écrire une requête linq pour chaque option sélectionnée. Mais ce ne serait pas possible si l'option filter augmentait.Est - ce qu'il y a une meilleure façon.

Merci!

enter image description here

C'est ce que j'ai fait dans mon contrôleur.(actuellement dropdown a deux options, excluant: "-- select one --")

public ActionResult StockLevel(string option, string batch, string name)
{
    if (option != "0" && batch == "" && name == "")
    {
        if(option == "BelowMin")
        {
            List<Stock> stk = (from s in db.Stocks
                               where s.Qty < s.Item.AlertQty
                               select s).ToList();
            return View(stk);
        }
        else
        {
            List<Stock> stk = (from s in db.Stocks
                               where s.Qty == s.InitialQty
                               select s).ToList();
            return View(stk);
        }
    }
    if (option == "0" && batch != "" && name == "")
    {
        List<Stock> stk = (from s in db.Stocks
                           where s.BatchNo == batch
                           select s).ToList();
        return View(stk);
    }
    if (option == "0" && batch == "" && name != "")
    {
        List<Stock> stk = (from s in db.Stocks
                           where s.Item.Name.StartsWith(""+name+"")
                           select s).ToList();
        return View(stk);
    }
    return View(db.Stocks.ToList());
}
26
demandé sur Reza Aghaei 2015-10-15 19:36:18

3 réponses

je vous recommande de séparer les préoccupations et l'utilisation d'une approche que le code dans votre contrôleur être comme ça, simple, beau et extensible:

public ActionResult Index(ProductSearchModel searchModel)
{
    var business = new ProductBusinessLogic();
    var model = business.GetProducts(searchModel);
    return View(model);
}

prestations:

  • Vous pouvez mettre tout ce dont vous avez besoin dans votre ProductSearchModel selon vos besoins.
  • vous pouvez écrire n'importe quelle logique dans GetProducts basé sur les besoins. Il n'y a pas de limitation.
  • si vous ajoutez un nouveau champ ou une nouvelle option de recherche, votre action et le contrôleur restera intact.
  • si la logique de votre recherche change, votre action et votre controller resteront intacts.
  • vous pouvez réutiliser la logique de recherche partout où vous avez besoin de rechercher sur les produits, dans les contrôleurs ou même dans d'autres logiques d'affaires.
  • ayant un tel ProductSearchModel, vous pouvez l'utiliser comme modèle de ProductSearch vue partielle et que vous pouvez appliquer DataAnnotations d'améliorer la validation du modèle et d'aider L'UI à le rendre en utilisant Display ou d'autres attribut.
  • vous pouvez ajouter une autre logique commerciale liée à votre produit dans cette classe de logique commerciale.
  • en suivant cette voie vous pouvez avoir une application plus organisée.

Exemple De Mise En Oeuvre:

supposons que vous ayez un Product catégorie:

public class Product
{
    public int Id { get; set; }
    public int Price { get; set; }
    public string Name { get; set; }
}

Vous pouvez créer un ProductSearchModel la classe et de mettre quelques champs que vous souhaitez faire une recherche basée sur:

public class ProductSearchModel
{
    public int? Id { get; set; }
    public int? PriceFrom { get; set; }
    public int? PriceTo { get; set; }
    public string Name { get; set; }
}

Ensuite, vous pouvez mettre votre logique de recherche ProductBusinessLogic classe de cette façon:

public class ProductBusinessLogic
{
    private YourDbContext Context;
    public ProductBusinessLogic()
    {
        Context = new YourDbContext();
    }

    public IQueryable<Product> 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;     
    }
}

Puis dans votre ProductController vous pouvez utiliser de cette façon:

public ActionResult Index(ProductSearchModel searchModel)
{
    var business = new ProductBusinessLogic();
    var model = business.GetProducts(searchModel);
    return View(model);
}

Note Importante:

dans une implémentation réelle, s'il vous plaît envisager d'implémenter unDispose modèle pour votre classe affaires pour disposer du contexte db au besoin. Pour plus d'informations, jetez un oeil à implémentation d'une méthode D'élimination ou Eliminer Le Motif.

61
répondu Reza Aghaei 2017-11-19 09:31:48

filtrage Conditionnel

.ToList(),.First(),.Count() et quelques autres méthodes exécutent la requête LINQ finale. Mais avant d'exécution, vous pouvez appliquer des filtres comme ça:

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

Wherif LINQ Extension

Simple WhereIf peut simplifier considérablement le code:

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

Si la mise en œuvre. C'est une méthode d'extension simple pour IQueryable:

public static class CollectionExtensions
{
    public static IQueryable<TSource> WhereIf<TSource>(
        this IQueryable<TSource> source,
        bool condition,
        Func<TSource, bool> predicate)
    {
        if (condition)
            return source.Where(predicate).AsQueryable();
        else
            return source;
    }
}

Non-Wherif LINQ way (Recommandé)

WhereIf fournit une façon plus déclarative, si vous ne voulez pas utiliser les extensions, vous pouvez simplement filtrer comme ça:

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

Cela donne exactement le même effet que WhereIf et cela fonctionnera plus rapidement car runtime aura besoin de construire juste un ExpressionTree au lieu de construire plusieurs arbres et de les fusionner.

12
répondu Andrei 2017-01-12 14:26:16
public ActionResult Index(string searchid)
{ 
var personTables = db.PersonTables.Where(o => o.Name.StartsWith(searchid) )||  o.CombanyTable.ComName.StartsWith(searchid) ).Include(k => k.CombanyTable);
return View(personTables.ToList());
}
0
répondu ana 2018-04-04 11:10:04