Может ли выражение 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"),
Ответы
Ответ 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;