动态构建LINQ表达式:同时实现ToLower与Contains方法
解决方案
要实现x.Key.ToLower().Contains("hoa")的动态表达式,需要同时处理字段调用ToLower()和搜索值转为小写两个步骤,具体修改如下:
步骤1:获取ToLower方法的MethodInfo
在获取containsMethod的位置,新增获取string.ToLower()的方法信息:
MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) }); // 新增:获取string.ToLower()无参方法 MethodInfo toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes);
步骤2:修改Contains分支的逻辑
在case ':'分支中,先对字段调用ToLower(),再将搜索常量转为小写后调用Contains:
case ':': // 1. 对字段属性调用ToLower() MethodCallExpression lowerMemberExpr = Expression.Call(member, toLowerMethod); // 2. 将搜索值转为小写,确保两边大小写一致 string lowerSearchValue = searchCriteria.Value.ToString().ToLower(); ConstantExpression lowerConstant = Expression.Constant(Convert.ChangeType(lowerSearchValue, member.Type)); // 3. 在ToLower()的结果上调用Contains return Expression.Call(lowerMemberExpr, containsMethod, lowerConstant);
完整修改后的代码
private static Expression GetExpressionCase<T>(ParameterExpression param, SearchCriteria searchCriteria) { MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) }); // 新增:获取string.ToLower()方法 MethodInfo toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes); MemberExpression member = Expression.Property(param, searchCriteria.Key); ConstantExpression constant = Expression.Constant(Convert.ChangeType(searchCriteria.Value, member.Type)); switch (searchCriteria.Operation) { case '=': return Expression.Equal(member, constant); case '>': return Expression.GreaterThanOrEqual(member, constant); case '<': return Expression.LessThanOrEqual(member, constant); case ':': // 对字段调用ToLower() var lowerMemberExpr = Expression.Call(member, toLowerMethod); // 搜索值转为小写 var lowerSearchValue = searchCriteria.Value.ToString().ToLower(); var lowerConstant = Expression.Constant(Convert.ChangeType(lowerSearchValue, member.Type)); // 调用Contains return Expression.Call(lowerMemberExpr, containsMethod, lowerConstant); } return null; }
说明
- 同时转换字段和搜索值为小写,能确保完全的大小写不敏感匹配,避免仅转换字段时可能出现的边缘情况。
ToLower()是EF Core PostgreSQL提供器支持的标准字符串方法,能被正确翻译为SQL的LOWER()函数,不会出现无法翻译的问题。
内容的提问来源于stack exchange,提问作者Son Bui
相关产品推荐
相关产品推荐

