使用多个字段过滤/搜索 - ASP.NET MVC

Avi*_*i-B 34 .net c# linq asp.net-mvc entity-framework

我使用ASP.NET MVCEF 6.

我有一个库存页面,显示库存商品的所有信息.现在我想要过滤记录.

在下图中我有3个选项.我可以按每个选项进行过滤,一次一个,或者两个或全部三个组合.

我正在考虑为所选的每个选项编写linq查询.但是如果过滤器选项增加,这将是不可能的.有更好的方法.

谢谢!

在此输入图像描述

这就是我在我的控制器中所做的.(目前下拉有两个选项,不包括:" - 选择一个 - ")

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());
}
Run Code Online (Sandbox Code Playgroud)

Rez*_*aei 76

我建议你单独关注并使用一种方法,控制器中的代码就像这样,简单,美观和可扩展:

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

优点:

  • 您可以ProductSearchModel根据自己的要求提供所需的任何物品.
  • 您可以GetProducts根据要求编写任何逻辑.没有限制.
  • 如果添加新字段或选项进行搜索,则操作和控制器将保持不变.
  • 如果搜索逻辑发生变化,您的操作和控制器将保持不变.
  • 您可以在需要搜索产品,控制器甚至其他业务逻辑的任何地方重用搜索逻辑.
  • 有了这样ProductSearchModel,您可以将其用作ProductSearch局部视图的模型,您可以应用DataAnnotations它来增强模型验证并帮助UI使用Display其他属性渲染它.
  • 您可以在该业务逻辑类中添加与产品相关的其他业务逻辑.
  • 按照这种方式,您可以拥有更有条理的应用程序.

示例实施:

假设你有一个Product班级:

public class Product
{
    public int Id { get; set; }
    public int Price { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

您可以创建一个ProductSearchModel类并根据它们放置一些您想要搜索的字段:

public class ProductSearchModel
{
    public int? Id { get; set; }
    public int? PriceFrom { get; set; }
    public int? PriceTo { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样把你的搜索逻辑放在ProductBusinessLogic课堂上:

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;     
    }
}
Run Code Online (Sandbox Code Playgroud)

然后ProductController你可以用这种方式:

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

重要的提示:

在实际的实现中,请考虑Dispose为您的业务类实现合适的模式,以便在需要时配置db上下文.有关更多信息,请参阅实现Dispose方法Dispose Pattern.

  • @KayGee最好提一个受这篇文章启发的新问题,让社区帮助你.另外如果你通知我,我当然也会看看你的问题:) (3认同)

And*_*rei 15

条件过滤

.ToList(),.First(),.Count()和其他一些方法来执行最后的LINQ查询.但在执行之前,您可以像这样应用过滤器:

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
Run Code Online (Sandbox Code Playgroud)

其中LINQ扩展

简单WhereIf可以显着简化代码:

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

WhereIf实施.这是一个简单的扩展方法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;
    }
}
Run Code Online (Sandbox Code Playgroud)

非WhereIf LINQ方式(推荐)

WhereIf 提供更多的声明方式,如果你不想使用扩展,你可以像这样过滤:

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

它提供了完全相同的效果,WhereIf并且它将更快地工作,因为运行时只需构建一个ExpressionTree而不是构建多个树并合并它们.