Problema LINQ C # con distinzione tra maiuscole e minuscole
-
03-07-2019 - |
Domanda
Ho questo:
var sortName = Request.Params["sortName"];
var query = Request.Params["query"];
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).Contains(query));
Il "uen.GetPropValue<string>(sortName)"
verrà riempito dinamicamente con il sortName che l'utente ha digitato nella pagina.
Ad esempio, se un utente cerca una persona di nome " Joe " lo snippet sarà:
(uen => uen.namePerson.Contains(Joe))
Ma sto riscontrando problemi con le ricerche sensibili al maiuscolo / minuscolo di LINQ. Se scrivo & Quot; Joe & Quot ;, lo farò. D'altra parte, se digito & Quot; joe & Quot; non porta nulla.
Come posso fare questo " Contiene (sortName) " funziona con Case-Insensitive ?? Ho provato alcune cose con String.Comparer ma riporta errori sulla soluzione di build.
Grazie !!
Soluzione
Credo che quanto segue genererà SQL corretto:
uen=>(uen.GetPropValue<string>(sortName)).ToLower().Contains(query.ToLower()))
Altri suggerimenti
Se si tratta davvero di LINQ-to-SQL, provare a utilizzare SqlMethods.Like anziché String.Contains.
Tuttavia, penso che il problema sia che NON si tratta di LINQ-to-SQL, poiché si utilizzano delegati anziché alberi di espressioni. Quindi questo viene portato lato client, quindi eseguito localmente (& Quot; LINQ to Objects & Quot;). Quindi, String.Contains sta facendo ciò che fa localmente.
In questo modo, la risposta di James è corretta, dal momento che sta chiamando ToLower () sia sul valore che sulla query. (Tuttavia, fai attenzione ai problemi della cultura, forse specifica quale cultura desideri.)
È inoltre possibile utilizzare il metodo String.IndexOf (String, Int32, StringComparison) ( http://msdn.microsoft.com/en-us/library/ms224424.aspx ). Questo metodo consente di specificare se la corrispondenza deve essere fatta in modo sensibile al maiuscolo / minuscolo e se deve utilizzare una cultura invariante o meno.
Quindi nel tuo esempio:
Func<UsuarioEndereco, bool> whereClause = (uen => uen.GetPropValue<string>(sortName).IndexOf(query, 0, StringComparison.OrdinalIgnoreCase));
Non sto commentando se questa è una soluzione migliore di quella fornita da James Curran. Potrebbe o non potrebbe essere, per quanto riguarda le prestazioni.
Questo è l'intero codice:
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));
Il metodo di estensione GetPropValue è:
public static T GetPropValue<T>(this object component, string propertyName)
{
return (T)TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);
}