Подтвердить что ты не робот

Может ли выражение linq быть нечувствительным к регистру

Я использую этот проект, чтобы использовать jqgrid для фильтрации и сортировки коллекций. Единственная недостающая особенность заключается в том, что этот пример не делает регистр, нечувствительный к регистру, который мне нужен.

Итак, если пользователь вводит "Тест", я хочу, чтобы он соответствовал "ТЕСТ", "ТЕСТ" и т.д..

У меня есть код, который выглядит так:

            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;

так или иначе, чтобы эти проверки ниже были нечувствительны к регистру, поэтому "Тест" будет равен "TEST"

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

Ответ 1

К сожалению, BCL не имеет перегрузки Contains, которая позволяет указать случайную инвариантность. Вам нужно будет перенести правильную перегрузку IndexOf в качестве обходного пути (проверяя, больше ли результат IndexOf больше нуля):

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

Этот MethodInfo принимает string и StringComparison, которые позволят вам указать StringComparison.OrdinalIgnoreCase, если хотите.

Ответ 2

Вы можете преобразовать оба значения в нижний регистр перед выполнением сравнения. Вот пример для 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;

Обратите внимание, что этот не пройдет тест Турции.

Ответ 3

Вы получите это следующим образом:

Первый Расширить класс string:

internal static class StringExtensions

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

Теперь напишите Expression call как

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;