может ли выражение linq быть нечувствительным к регистру - PullRequest
12 голосов
/ 15 марта 2011

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

Так что, если пользователь вводит "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"),

Ответы [ 4 ]

18 голосов
/ 15 марта 2011

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

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

9 голосов
/ 15 марта 2011

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

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

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

2 голосов
/ 13 июня 2012
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;
2 голосов
/ 22 июля 2011

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

Первый класс расширения строки:

internal static class StringExtensions

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

Теперь запишите выражение Expression как

Expression.Call(null,
                    typeof(StringExtensions).GetMethod("ContainsExt", new Type[] { typeof(String), typeof(String) }),
                    new[] { memberAccessToString, Expression.Constant(value));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...