EF Core全局查询过滤器复杂Expression表达式无法翻译问题问询
问题原因
你当前表达式构建逻辑使用了Expression.Invoke调用独立的子Lambda表达式,EF Core全局查询过滤器的表达式翻译规则不支持这种嵌套调用结构,而普通Where查询的翻译逻辑对该结构兼容度更高,所以才会出现普通查询可用、全局过滤器报错的情况。
解决方案
直接构造原生的EF.Functions.Like方法调用表达式,去掉Expression.Invoke嵌套逻辑,修改后的代码如下:
private Expression<Func<AssessmentModel, bool>> GetAssessmentFilter() { var assessmentParameter = Expression.Parameter(typeof(AssessmentModel), "a"); // 获取EF.Functions.Like方法的元数据 var likeMethod = typeof(DbFunctionsExtensions) .GetMethod(nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), typeof(string), typeof(string) }); var efFunctionsConstant = Expression.Constant(EF.Functions); // 构造每个keyword对应的Like条件表达式 var orConditions = _adminTeamNames .Select(keyword => Expression.Call( likeMethod, efFunctionsConstant, Expression.Property(assessmentParameter, nameof(AssessmentModel.Owners)), Expression.Constant($"%{keyword}%") )) .ToList(); // 拼接OR逻辑 var orExpressionTree = orConditions .Skip(1) .Aggregate( orConditions.First(), (current, expression) => Expression.OrElse(expression, current)); // 生成最终的过滤Lambda return Expression.Lambda<Func<AssessmentModel, bool>>(orExpressionTree, assessmentParameter); }
可选优化(规避模糊匹配冲突)
当前用%{keyword}%的模糊匹配可能出现误匹配问题,比如keyword为team1时会匹配到Owners为team10;team2的数据。如果需要完全匹配分号分隔的所有者项,可以调整匹配逻辑:
// 拼接条件改为:;{Owners}; 包含 ;{keyword}; .Select(keyword => Expression.Call( likeMethod, efFunctionsConstant, // 给字段值前后加分号 Expression.Add( Expression.Add(Expression.Constant(";"), Expression.Property(assessmentParameter, nameof(AssessmentModel.Owners))), Expression.Constant(";") ), Expression.Constant($";{keyword};") ))
内容的提问来源于stack exchange,提问作者Colin DeClue
相关产品推荐
相关产品推荐

