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

如何让LINQ表达式中的Contains搜索实现大小写不敏感?

问题:让Expression生成的Contains搜索支持大小写不敏感

我编写了一个用于创建Expression的方法处理搜索逻辑,代码如下:

private static Expression GenerateExpressionForString(Expression left, ItemComparisonOperator itemComparisonOperator,
    object value)
{
    StringComparisonOperator stringOperator = Enum.Parse<StringComparisonOperator>(itemComparisonOperator.ToString());
    ConstantExpression constant = Expression.Constant(value, left.Type);

    if (stringOperator is StringComparisonOperator.Equal or StringComparisonOperator.NotEqual)
    {
        ExpressionType nativeComparison = Enum.Parse<ExpressionType>(stringOperator.ToString());
        return Expression.MakeBinary(nativeComparison, left, constant);
    }

    if (stringOperator is StringComparisonOperator.Contains)
    {
        return Expression.Call(left, stringOperator.ToString(), Type.EmptyTypes, constant); 
    }
    
    if (stringOperator is StringComparisonOperator.StartsWith
        or StringComparisonOperator.EndsWith)
        return Expression.Call(left, stringOperator.ToString(), Type.EmptyTypes, constant);

    throw new NotSupportedException($"Invalid comparison operator '{itemComparisonOperator}'.");
}

目前该方法除Contains搜索外均正常工作,但Contains搜索是大小写敏感模式,请问如何修改代码实现大小写不敏感?


解决方案

要实现大小写不敏感的Contains搜索,有两种常用方案,可根据你的场景选择:

方案1:调用带StringComparison参数的Contains重载

string.Contains提供了接受StringComparison枚举的重载,传入StringComparison.OrdinalIgnoreCase(或其他忽略大小写的枚举值)即可实现不敏感匹配。修改Contains分支代码如下:

if (stringOperator is StringComparisonOperator.Contains)
{
    // 生成StringComparison.OrdinalIgnoreCase的常量表达式
    var stringComparisonExpr = Expression.Constant(StringComparison.OrdinalIgnoreCase);
    // 调用string.Contains(string value, StringComparison comparisonType)重载
    return Expression.Call(
        left,
        nameof(string.Contains),
        Type.EmptyTypes,
        constant,
        stringComparisonExpr
    );
}

注意:如果表达式最终要转换为EF Core等ORM查询,需确认ORM支持该重载的翻译(EF Core 3.0+已支持)。

方案2:统一转为小写/大写后比较

若场景不支持方案1(比如旧版ORM不识别带参数的Contains重载),可以将左表达式和常量值统一转为小写(或大写)后再调用Contains:

if (stringOperator is StringComparisonOperator.Contains)
{
    // 左表达式转小写
    var toLowerLeft = Expression.Call(left, nameof(string.ToLower), Type.EmptyTypes);
    // 常量值转小写(需确保value不为null,可提前加null检查)
    var lowerConstant = Expression.Constant(((string)value).ToLower(), left.Type);
    // 调用小写后的Contains方法
    return Expression.Call(toLowerLeft, nameof(string.Contains), Type.EmptyTypes, lowerConstant);
}

完整修改后的代码(以方案1为例)

private static Expression GenerateExpressionForString(Expression left, ItemComparisonOperator itemComparisonOperator,
    object value)
{
    StringComparisonOperator stringOperator = Enum.Parse<StringComparisonOperator>(itemComparisonOperator.ToString());
    ConstantExpression constant = Expression.Constant(value, left.Type);

    if (stringOperator is StringComparisonOperator.Equal or StringComparisonOperator.NotEqual)
    {
        ExpressionType nativeComparison = Enum.Parse<ExpressionType>(stringOperator.ToString());
        return Expression.MakeBinary(nativeComparison, left, constant);
    }

    if (stringOperator is StringComparisonOperator.Contains)
    {
        var stringComparisonExpr = Expression.Constant(StringComparison.OrdinalIgnoreCase);
        return Expression.Call(
            left,
            nameof(string.Contains),
            Type.EmptyTypes,
            constant,
            stringComparisonExpr
        );
    }
    
    if (stringOperator is StringComparisonOperator.StartsWith
        or StringComparisonOperator.EndsWith)
    {
        // 可选:给StartsWith/EndsWith也添加大小写不敏感支持
        var stringComparisonExpr = Expression.Constant(StringComparison.OrdinalIgnoreCase);
        return Expression.Call(
            left,
            stringOperator.ToString(),
            Type.EmptyTypes,
            constant,
            stringComparisonExpr
        );
    }

    throw new NotSupportedException($"Invalid comparison operator '{itemComparisonOperator}'.");
}

内容的提问来源于stack exchange,提问作者Eugene Sukh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:20:54