Проблема с C # LINQ с учетом регистра
-
03-07-2019 - |
Вопрос
У меня есть это:
var sortName = Request.Params["sortName"];
var query = Request.Params["query"];
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).Contains(query));
В "uen.GetPropValue<string>(sortName)"
будет динамически заполняться именем сортировки, введенным пользователем на странице.
Например, если пользователь ищет человека по имени "Джо", фрагмент будет:
(uen => uen.namePerson.Contains(Joe))
Но у меня возникли проблемы с поиском с учетом регистра LINQ.Если я наберу "Джо", я сделаю что-нибудь.С другой стороны, если я наберу "джо", это ничего не принесет.
Как я могу сделать так, чтобы это "Содержит (sortName)" работало без учета регистра??Я попробовал кое-что с String.Comparer, но он сообщает об ошибках при сборке решения.
Спасибо!!
Решение
Я полагаю, что следующее сгенерирует правильный SQL:
uen=>(uen.GetPropValue<string>(sortName)).ToLower().Contains(query.ToLower()))
Другие советы
Если это действительно LINQ-to-SQL, попробуйте использовать Методы SqlMethods.Like метод вместо строки.Содержит.
Однако, я думаю, проблема в том, что это НЕ LINQ-to-SQL , потому что вы используете делегаты вместо деревьев выражений.Таким образом, это переносится на сторону клиента, а затем выполняется локально ("LINQ to Objects").Следовательно, String.Contains делает то, что он делает локально.
Таким образом, ответ Джеймса верен, поскольку он вызывает ToLower() как для значения, так и для запроса.(Хотя, остерегайтесь проблем с культурой - возможно, укажите, какую культуру вы хотите.)
Вы также могли бы использовать String.Метод indexOf (String, Int32, сравнение строк) (http://msdn.microsoft.com/en-us/library/ms224424.aspx).Этот метод позволяет вам указать, должно ли сопоставление выполняться с учетом регистра или нет, и должен ли он использовать инвариантный язык или нет.
Итак, в вашем примере:
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).IndexOf(query, 0, StringComparison.OrdinalIgnoreCase));
Я не комментирую, является ли это лучшим решением, чем то, которое предоставил Джеймс Карран.Это могло быть, а могло и не быть, с точки зрения производительности.
Это весь код целиком:
var sortOrder = Request.Params["sortorder"];
var sortName = Request.Params["sortname"];
var query = Request.Params["query"];
IEnumerable<UsuarioEndereco> pagedEndereco;
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).Contains(query));
pagedEndereco = sortOrder.Equals("asc", StringComparison.CurrentCultureIgnoreCase) ?
_agendaServico.SelecionaUsuarioEnderecos(u.codUsuario).Where(whereClause).OrderByDescending(uen => uen.GetPropValue<IComparable>(sortName)) :
_agendaServico.SelecionaUsuarioEnderecos(u.codUsuario).Where(whereClause).OrderBy(uen => uen.GetPropValue<IComparable>(sortName));
Метод расширения GetPropValue является:
public static T GetPropValue<T>(this object component, string propertyName)
{
return (T)TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);
}