【问题标题】:can linq expression be case insensitivelinq 表达式可以不区分大小写吗
【发布时间】:2011-03-14 22:44:12
【问题描述】:

我正在利用this project to use jqgrid to filter and sort collections。一个缺失的功能是这个例子没有做我需要的不区分大小写的搜索。

因此,如果用户键入“Test”,我希望它与“TEST”、“TeST”等匹配。 .

我的代码如下所示:

            case WhereOperation.Equal:
                condition = Expression.Equal(memberAccessToString, filter);
                lambda = Expression.Lambda(condition, parameter);
                break;
            case WhereOperation.NotEqual:
                condition = Expression.NotEqual(memberAccessToString, filter);
                lambda = Expression.Lambda(condition, parameter);
                break;
            case WhereOperation.Contains:
                condition = Expression.Call(memberAccessToString,
                    typeof(string).GetMethod("Contains"),
                    Expression.Constant(value));
                lambda = Expression.Lambda(condition, parameter);
                break;

下面是否有这些检查不区分大小写,因此“测试”将等于“测试”

Expression.NotEqual    
Expression.Equal
Expression.Call(memberAccessToString,
                    typeof(string).GetMethod("Contains"),

【问题讨论】:

  • 问题是(即使可能)你为什么需要它?似乎有一个设计问题 - 你能详细说明一下吗?
  • @BrokenGlass - 我正在使用此代码通过一些用户输入过滤集合。这里没有设计问题。用户可以输入“test”或“test”
  • 那我理解错了,谢谢澄清
  • 是否可以同时在过滤字符串和过滤值上调用ToLower(可能使用Expression.Call)?
  • 您不能总是将用户输入格式化为小写然后进行比较吗?

标签: c# linq comparison expression


【解决方案1】:

在进行比较之前,您可以将两个值都转换为小写。这是Contains 的示例:

case WhereOperation.Contains:
    var toLower = Expression.Call(memberAccessToString,
                                  typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
    condition = Expression.Call(toLower,
                                typeof(string).GetMethod("Contains"),
                                Expression.Constant(value.ToString().ToLower()));
    lambda = Expression.Lambda(condition, parameter);
    break;

但是请注意,这个won't pass the Turkey test

【讨论】:

    【解决方案2】:

    不幸的是,BCL 没有Contains 重载允许您指定大小写不变性。您将不得不获取IndexOf 的正确重载作为解决方法(检查IndexOf 的结果是否大于零):

    var methodInfo 
        = typeof(string)
            .GetMethod("IndexOf", 
                new[] { typeof(string), typeof(StringComparison) });
    

    MethodInfo 接受stringStringComparison,如果您愿意,可以指定StringComparison.OrdinalIgnoreCase

    【讨论】:

    • @Andrew Hare - 你能澄清你的答案吗?我对你的回复有点困惑。 .下面的代码将如何进行不区分大小写的搜索??
    • @ooo:我只是在写一个答案,但是由于 Andrew 已经涵盖了最重要的部分,所以下面是其余部分: var callEx = Expression.Call(memberAccessToString, method, Expression.Constant(值),Expression.Constant(StringComparison.OrdinalIgnoreCase));条件 = Expression.NotEqual(callEx, Expression.Constant(-1));
    • @Ani - 你从哪里得到“方法”??
    • @ooo:这是 Andrew 的回答中的methodInfo
    • @ooo - 抱歉,不会。这段代码只是给你MethodInfo,你需要自己做一个不区分大小写的“包含”实现。
    【解决方案3】:

    您可以通过以下方式获得它:

    首先扩展字符串类:

    internal static class StringExtensions
    
        {
            public static bool ContainsExt(this String str, string val)
            {
                return str.IndexOf(val, StringComparison.InvariantCultureIgnoreCase) > -1 ? true : false;
            }
        }
    

    现在将表达式调用写成

    Expression.Call(null,
                        typeof(StringExtensions).GetMethod("ContainsExt", new Type[] { typeof(String), typeof(String) }),
                        new[] { memberAccessToString, Expression.Constant(value));
    

    【讨论】:

      【解决方案4】:
      case WhereOperation.Contains:
           var callEx = Expression.Call(memberAccess, typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) }), Expression.Constant(value), Expression.Constant(StringComparison.OrdinalIgnoreCase));
           condition = Expression.NotEqual(callEx, Expression.Constant(-1));
           lambda = Expression.Lambda(condition, parameter);
           break;
      

      【讨论】:

        猜你喜欢
        • 2021-07-05
        • 2010-09-07
        • 1970-01-01
        • 2011-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多