如何构建可在Queryable查询中复用的过滤条件
问题根因
IQueryable 类型的 Where 扩展方法接收的参数是 Expression<Func<T, bool>> 类型的表达式树,ORM 需要把表达式树翻译为 SQL 语句执行。你封装的普通 isProspect 方法属于 C# 本地方法,无法被表达式树解析器识别,自然不能翻译成合法 SQL,因此运行报错。
复用条件实现方案
核心思路就是把查询条件直接封装为表达式树结构,供 IQueryable 直接使用。
方案1:表达式属性(无额外参数场景)
直接把固定的查询条件封装为表达式属性:
private Expression<Func<FicFicheCrm, bool>> IsProspect => ficheCrm => _context.FicDernierEvt .Where(y => y.VteAffaire == null && y.ApvAffaire == null) .Select(y => y.IdFicheCrm) .Contains(ficheCrm.Id);
调用方式非常简单,直接把属性传入 Where 即可:
query = query.Where(IsProspect);
方案2:返回表达式的方法(需动态传参场景)
如果查询条件需要接收动态参数,就封装为返回表达式树的方法,比如需要额外传入事件状态过滤:
private Expression<Func<FicFicheCrm, bool>> GetIsProspectPredicate(int eventStatus) { return ficheCrm => _context.FicDernierEvt .Where(y => y.VteAffaire == null && y.ApvAffaire == null && y.Status == eventStatus) .Select(y => y.IdFicheCrm) .Contains(ficheCrm.Id); }
调用时传入参数即可:
query = query.Where(GetIsProspectPredicate(1));
注意事项
- 不要主动调用表达式的
Compile()方法,否则会把查询转换为内存中执行的IEnumerable查询,导致全表数据拉取到本地过滤,严重影响性能。 - 如果需要把多个复用的表达式条件组合使用,可以借助 LinqKit 等库的表达式拼接能力,实现多条件动态组合。
内容的提问来源于stack exchange,提问作者Qgruber
相关产品推荐
相关产品推荐

