如何在动态表达式中结合Contains与ToLower实现通用搜索?
解决表达式树结合Contains与ToLower的通用搜索问题
你的代码目前只对搜索字符串做了ToLower()处理,但没有将目标属性的字符串值也转为小写,这会导致大小写不匹配的内容无法被检索到。另外还需要处理属性值为null的场景,避免调用ToLower()时抛出空引用异常。
修改后的完整代码
Type elementType = typeof(TItem); PropertyInfo[] stringProperties = elementType.GetProperties() .Where(x => x.PropertyType == typeof(string)) .ToArray(); MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) })!; MethodInfo toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes)!; ParameterExpression paramExp = Expression.Parameter(elementType); IEnumerable<Expression> expressions = stringProperties.Select(p => { // 获取属性表达式 Expression propertyExp = Expression.Property(paramExp, p); // 处理属性值为null的情况,转为空字符串后再转小写 Expression safePropertyExp = Expression.Coalesce(propertyExp, Expression.Constant(string.Empty)); // 调用ToLower()方法统一大小写 Expression lowerPropertyExp = Expression.Call(safePropertyExp, toLowerMethod); // 调用Contains方法,传入小写后的搜索字符串 return Expression.Call(lowerPropertyExp, containsMethod, Expression.Constant(this.searchString.ToLower())); }); // 使用OrElse替代Or,实现逻辑或的短路求值(更符合常规判断逻辑) Expression body = expressions.Aggregate((prev, current) => Expression.OrElse(prev, current)); var lambda = Expression.Lambda<Func<TItem, bool>>(body, paramExp);
关键改动说明
- 统一大小写匹配:在调用
Contains前,对属性值也执行ToLower(),确保搜索字符串和属性值在同一大小写规则下进行匹配。 - 空值安全处理:通过
Expression.Coalesce将null的属性值替换为空字符串,避免触发NullReferenceException。 - 逻辑优化:把
Expression.Or替换为Expression.OrElse,实现逻辑或的短路求值,提升判断性能且符合常规业务逻辑预期。
内容的提问来源于stack exchange,提问作者Leño77
相关产品推荐
相关产品推荐

