如何避免Razor Page未应用过滤器时加载数据库全部行?
解决方案:保留OnGet逻辑,实现未过滤时不加载数据
核心思路
通过统一判断是否有过滤器被激活,仅在存在有效过滤器时执行数据库查询,否则直接返回空列表。这种方式无需修改为OnPost,同时避免了全量数据加载的问题,还能让代码更整洁。
步骤1:添加过滤器激活状态判断方法
在你的PageModel类中新增一个方法,统一检查所有过滤器开关是否有激活的:
private bool HasActiveFilters() { // 将所有过滤器开关属性放入数组,判断是否有任意一个为true return new[] { GrassSwitch, FireSwitch /* 补充其他过滤器开关 */ }.Any(switchVal => switchVal); }
步骤2:修改OnGetAsync逻辑
调整原有查询逻辑,仅在存在激活过滤器时执行数据库查询,否则返回空列表:
public async Task OnGetAsync() { // 默认初始化为空列表 Pokedex = new List<Pokedex>(); if (HasActiveFilters()) { var query = _context.Pokedex.AsQueryable(); if (GrassSwitch) { query = query.Where(p => p.type1 == "grass" || p.type2 == "grass"); } if (FireSwitch) { query = query.Where(p => p.type1 == "fire" || p.type2 == "fire"); } // ...其他过滤器逻辑保持不变... Pokedex = await query.ToListAsync(); } // 注:原代码中的SaveChangesAsync是多余的,仅查询操作无需保存更改 // await _context.SaveChangesAsync(); }
可选优化:提取重复过滤逻辑
如果有多个同类型的过滤器(比如各种属性类型的开关),可以进一步提取通用方法减少代码重复:
private IQueryable<Pokedex> ApplyTypeFilter(IQueryable<Pokedex> query, string targetType) { return query.Where(p => p.type1 == targetType || p.type2 == targetType); }
然后在查询逻辑中替换为:
if (GrassSwitch) query = ApplyTypeFilter(query, "grass"); if (FireSwitch) query = ApplyTypeFilter(query, "fire");
效果说明
- 页面初始加载或所有过滤器关闭时:
HasActiveFilters()返回false,Pokedex保持空列表,不会执行任何数据库查询,完全避免全量数据加载。 - 任意过滤器激活时:正常执行过滤查询,返回匹配的数据。
内容的提问来源于stack exchange,提问作者Csharpmajor
相关产品推荐
相关产品推荐

