如何用动态Lambda表达式实现WHERE NOT IN子句逻辑?
动态构建Lambda表达式实现NOT IN筛选逻辑
要实现的目标对应硬编码逻辑:
List<Coverage>? excludedCoverage = originalCoverage.Where(a => !currentCoverage.Select(k => k.CoverageId).Contains(a.CoverageId)).ToList();
基于你已掌握的基础动态Lambda写法,以下是具体实现步骤及代码:
步骤1:提前提取需排除的CoverageId集合
先将currentCoverage中的CoverageId提取为单独集合,既简化表达式构建,也提升筛选效率:
var excludedIds = currentCoverage?.Select(k => k.CoverageId).ToList() ?? new List<int>();
步骤2:构建动态Lambda表达式
// 定义参数表达式,对应Lambda中的输入参数a var parameterExpression = Expression.Parameter(typeof(Coverage), "a"); // 获取a.CoverageId的属性访问表达式 var coverageIdProperty = Expression.Property(parameterExpression, "CoverageId"); // 构建排除ID集合的常量表达式 var excludedIdsConstant = Expression.Constant(excludedIds); // 获取List<int>.Contains方法的MethodInfo var containsMethod = typeof(List<int>).GetMethod("Contains", new[] { typeof(int) })!; // 构建调用Contains方法的表达式:excludedIds.Contains(a.CoverageId) var containsExpression = Expression.Call(excludedIdsConstant, containsMethod, coverageIdProperty); // 对Contains结果取反,实现NOT IN逻辑:!excludedIds.Contains(a.CoverageId) var notContainsExpression = Expression.Not(containsExpression); // 构建完整的Lambda表达式并编译 var lambda = Expression.Lambda<Func<Coverage, bool>>(notContainsExpression, parameterExpression); var filterDelegate = lambda.Compile();
步骤3:执行筛选
var excludedCoverage = originalCoverage?.Where(filterDelegate).ToList();
结果验证
用你提供的示例数据运行后,excludedCoverage将包含CoverageId为1、2、3的三个元素,与硬编码逻辑的输出完全一致。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

