C # LINQ проблема с учетом регистра - PullRequest
2 голосов
/ 06 марта 2009

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

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)" будет динамически заполняться sortName, введенным пользователем на странице.

Например, если пользователь ищет человека по имени «Джо», фрагмент будет выглядеть так:

(uen => uen.namePerson.Contains(Joe))

Но у меня проблемы с поиском с учетом регистра LINQ. Если я наберу "Джо", я буду что-то. С другой стороны, если я наберу "Джо", это ничего не принесет.

Как я могу сделать так, чтобы это "Contains (sortName)" работало с учетом регистра? Я пробовал кое-что с String.Comparer, но он сообщает об ошибках в решении для сборки.

Спасибо !!

Ответы [ 4 ]

6 голосов
/ 06 марта 2009

Я полагаю, что следующее сгенерирует правильный SQL:

 uen=>(uen.GetPropValue<string>(sortName)).ToLower().Contains(query.ToLower()))
2 голосов
/ 06 марта 2009

Если это действительно LINQ-to-SQL, попробуйте использовать метод SqlMethods.Like вместо String.Contains.

Однако, я думаю, проблема в том, что это НЕ LINQ-to-SQL, потому что вы используете делегаты вместо деревьев выражений. Таким образом, это выполняется на стороне клиента, а затем выполняется локально («LINQ to Objects»). Следовательно, String.Contains делает то, что делает локально.

Таким образом, ответ Джеймса верен, поскольку он вызывает ToLower () как для значения, так и для запроса. (Хотя остерегайтесь вопросов культуры - возможно, укажите, какую культуру вы хотите.)

1 голос
/ 29 октября 2010

Вы также можете использовать метод String.IndexOf (String, Int32, StringComparison) (http://msdn.microsoft.com/en-us/library/ms224424.aspx).). Этот метод позволяет указать, должно ли сопоставление выполняться с учетом регистра или нет, и следует ли использовать Инвариантная культура или нет.

Итак, в вашем примере:

Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).IndexOf(query, 0, StringComparison.OrdinalIgnoreCase));

Я не комментирую, если это лучшее решение, чем предложенное Джеймсом Керраном. Это может или не может быть, производительность мудрая.

0 голосов
/ 06 марта 2009

Это весь код:

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);
}
...