Вопрос

У меня есть это:

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);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top