ASP.NET MVC5 C# EF 下拉列表筛选产品及分页问题排查
核心问题排查
原有代码存在4个直接导致功能异常的问题:
- 类型不匹配:Action接收的筛选参数为
string类型,但CompanyID、CategoryID是可空int类型,直接用Equals比较字符串与数值类型,既会触发类型报错,也永远无法命中匹配结果 - 筛选逻辑不生效:给查询变量
prod追加筛选条件后,最终分页取数直接调用原始db.Products集合,前面追加的筛选条件完全没有被执行 - 不支持组合筛选:两个筛选分支互斥,只要命中公司筛选逻辑就会直接返回,不会叠加分类筛选条件,无法实现两个条件同时过滤
- 分页丢参数:分页控件的路由仅传递页码参数,翻页时会丢失已选择的公司、分类条件,翻页后直接回到全量产品列表
修复后的实现代码
1. Products控制器代码修改
namespace AMS_ITAMSdb.Controllers { public class ProductsController : Controller { private ItamsEntities db = new ItamsEntities(); // GET: Products public ActionResult Index(string prodCompany, string prodCategory, int? page) { // 初始化下拉列表,自动保留用户选中项 ViewBag.prodCompany = new SelectList(db.Companies, "CompanyID", "Brand_Name", prodCompany); ViewBag.prodCategory = new SelectList(db.ItemCategories, "CategoryID", "Category", prodCategory); // 初始化产品延迟查询,不立即执行数据库操作 IQueryable<Product> prodQuery = db.Products.AsQueryable(); // 处理公司筛选:字符串参数安全转可空int,转换成功才追加筛选条件 if (!string.IsNullOrEmpty(prodCompany) && int.TryParse(prodCompany, out int companyId)) { prodQuery = prodQuery.Where(x => x.CompanyID == companyId); } // 处理分类筛选:和公司筛选条件叠加生效,不互斥 if (!string.IsNullOrEmpty(prodCategory) && int.TryParse(prodCategory, out int categoryId)) { prodQuery = prodQuery.Where(x => x.CategoryID == categoryId); } // 统一排序、分页,所有筛选条件会被翻译成SQL在数据库端执行 int pageNumber = page ?? 1; int pageSize = 15; var pagedProducts = prodQuery.OrderBy(x => x.ProductID).ToPagedList(pageNumber, pageSize); return View(pagedProducts); } // 释放数据库上下文,补充原有代码遗漏的资源释放逻辑 protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } }
2. Index视图代码修改
视图中表格、表单部分无需调整,仅需修改分页控件的路由参数,追加筛选条件传递,避免翻页丢参:
<!-- 原有表格、表单代码保持不变,仅替换分页部分代码即可 --> <link href="~/Content/PagedList.css" rel="stylesheet" /> <div></div> (Page @(Model.PageCount < Model.PageNumber ? 0: Model.PageNumber)/@Model.PageCount) @Html.PagedListPager(Model, page => Url.Action("Index", new { page = page, prodCompany = Request.QueryString["prodCompany"], prodCategory = Request.QueryString["prodCategory"] }))
功能验证点
- 无任何筛选条件时,返回按
ProductID升序排列的全量分页产品,每页15条 - 仅选择公司时,返回对应公司下的全部分类产品,分页正常
- 仅选择分类时,返回对应分类下的所有公司产品,分页正常
- 同时选择公司和分类时,返回同时满足两个条件的产品,分页正常
- 翻页时自动保留已选的筛选条件,下拉框保持选中状态,不会重置为默认选项
int.TryParse会自动过滤非法参数(如手动篡改URL传入非数字的筛选值),不会抛出类型转换异常- 所有筛选、排序逻辑在数据库端执行,不会拉取全量数据到内存过滤,加载性能符合要求
内容的提问来源于stack exchange,提问作者Kip M.
相关产品推荐
相关产品推荐

