You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在动态表达式中结合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:55:25