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

我在EF 6中使用ASP.NET MVC

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

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

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

谢谢!

在此处输入图像描述

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

public ActionResult StockLevel(string option, string batch, string name) { if (option != "0" && batch == "" && name == "") { if(option == "BelowMin") { List stk = (from s in db.Stocks where s.Qty < s.Item.AlertQty select s).ToList(); return View(stk); } else { List stk = (from s in db.Stocks where s.Qty == s.InitialQty select s).ToList(); return View(stk); } } if (option == "0" && batch != "" && name == "") { List stk = (from s in db.Stocks where s.BatchNo == batch select s).ToList(); return View(stk); } if (option == "0" && batch == "" && name != "") { List stk = (from s in db.Stocks where s.Item.Name.StartsWith(""+name+"") select s).ToList(); return View(stk); } return View(db.Stocks.ToList()); } 

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

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

优点:

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

示例实施:

假设您有一个Product类:

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

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

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

然后,您可以通过以下方式将搜索逻辑放在ProductBusinessLogic类中:

 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; } } 

然后在您的ProductController您可以使用以下方式:

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

重要的提示:

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

条件过滤

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

 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 

其中LINQ扩展

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

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

WhereIf实施。 这是IQueryable的简单扩展方法:

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

非WhereIf LINQ方式(推荐)

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

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

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

 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()); }