.NET Core 2.2中Lambda实现Get方法过滤失效问题排查
问题根源:IQueryable的
Where方法不会修改原对象,而是返回新实例 嘿,这个问题我见过好多次啦——你犯了一个很容易忽略的IQueryable使用误区!
EF Core里的IQueryable<T>是基于查询表达式树工作的,Where方法不会直接修改你声明的analysis变量,而是返回一个包含新过滤条件的全新IQueryable实例。你现在只是调用了Where但没有把返回值重新赋值给analysis,所以原来的查询根本没被修改,最后执行ToList()的时候还是跑的原始全表查询,自然返回所有数据了。
修正后的代码
只需要给每个Where的结果重新赋值回analysis就行:
public List<Analysis> Get(Analysis filter) { #region Filter Validation IQueryable<Analysis> analysis = dbContext.Analysis; if (!string.IsNullOrEmpty(filter.BusinessLine)) // 关键:把Where返回的新IQueryable赋值给原变量 analysis = analysis.Where(a => a.BusinessLine == filter.BusinessLine); if (!string.IsNullOrEmpty(filter.Requisition)) analysis = analysis.Where(a => a.Requisition == filter.Requisition); if (!string.IsNullOrEmpty(filter.Clue)) analysis = analysis.Where(a => a.Clue == filter.Clue); if (filter.DateFrom.HasValue) analysis = analysis.Where(a => a.CreationDate >= filter.DateFrom); if (filter.DateTo.HasValue) analysis = analysis.Where(a => a.CreationDate <= filter.DateTo); if (!string.IsNullOrEmpty(filter.Text)) { analysis = analysis.Where(a => a.Requisition.Contains(filter.Text) || a.InsuranceClaimCity.Contains(filter.Text)); } #endregion return analysis.ToList(); }
补充说明
- EF Core的
IQueryable是延迟执行的:只有当你调用ToList()、FirstOrDefault()这类触发枚举的方法时,才会把表达式树转换成对应数据库的查询逻辑(内存数据库则是在内存中执行过滤)。 - 每个
Where调用都是在原表达式树的基础上追加新的过滤节点,生成一个新的IQueryable对象,如果不把这个新对象赋值回去,你的analysis变量始终指向最初的全表查询,过滤条件根本没被加入到最终执行的查询里。
内容的提问来源于stack exchange,提问作者Matheus Batista
相关产品推荐
相关产品推荐

