Problema de C # LINQ con mayúsculas y minúsculas
-
03-07-2019 - |
Pregunta
Tengo esto:
var sortName = Request.Params["sortName"];
var query = Request.Params["query"];
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).Contains(query));
El "uen.GetPropValue<string>(sortName)"
se llenará dinámicamente con el sortName que el usuario escribió en la página.
Por ejemplo, si un usuario busca a una persona llamada " Joe " ;, el fragmento será:
(uen => uen.namePerson.Contains(Joe))
Pero tengo problemas con las búsquedas de LINQ que distinguen entre mayúsculas y minúsculas. Si escribo & Quot; Joe & Quot ;, haré algo. Por otro lado, si escribo & Quot; joe & Quot ;, no trae nada.
¿Cómo puedo hacer esto " Contiene (sortName) " funciona con mayúsculas y minúsculas? He intentado algunas cosas con String.Comparer pero informa errores en la solución de compilación.
¡Gracias!
Solución
Creo que lo siguiente generará el SQL adecuado:
uen=>(uen.GetPropValue<string>(sortName)).ToLower().Contains(query.ToLower()))
Otros consejos
Si esto es realmente LINQ-to-SQL, intente usar el Método SqlMethods.Like en lugar de String.Contains.
Sin embargo, creo que el problema es que esto NO es LINQ-to-SQL, porque está utilizando delegados en lugar de árboles de expresión. Entonces esto se lleva al lado del cliente, luego se ejecuta localmente (& Quot; LINQ to Objects & Quot;). Por lo tanto, String.Contains está haciendo lo que hace localmente.
De esa manera, la respuesta de James es correcta, ya que está llamando a ToLower () tanto en el valor como en la consulta. (Aunque, tenga cuidado con los problemas culturales; quizás especifique qué cultura desea).
También puede usar el método String.IndexOf (String, Int32, StringComparison) ( http://msdn.microsoft.com/en-us/library/ms224424.aspx ). Este método le permite especificar si la coincidencia debe hacerse entre mayúsculas y minúsculas o no, y si debe usar una cultura Invariante o no.
Entonces, en tu ejemplo:
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).IndexOf(query, 0, StringComparison.OrdinalIgnoreCase));
No estoy comentando si esta es una mejor solución que la proporcionada por James Curran. Podría o no ser, en cuanto al rendimiento.
Este es el código completo:
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));
El método de extensión GetPropValue es:
public static T GetPropValue<T>(this object component, string propertyName)
{
return (T)TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);
}