2013-10-26 11 views
15

basa sulla risposta a questa domanda:Confronto stringhe maiuscole e minuscole non funzionante in C#?

How can I do a case insensitive string comparison?

Sto cercando di fare un confronto tra maiuscole e minuscole senza l'utilizzo di Confronto o ToLower:

var user = db.Users.FirstOrDefault(s => String.Equals(s.Username, username, StringComparison.OrdinalIgnoreCase)); 

Tuttavia ottengo un errore:

Incorrect number of arguments supplied for call to method 'Boolean Equals(System.String, System.String, System.StringComparison)'

Cosa sto sbagliando?

+0

Si è verificato che il nome utente e la s.Username sono di tipo stringa. – Tilak

+1

Piuttosto sicuro che L2S non supporta quel particolare metodo. Se questo fosse il codice C# reale eseguibile e non qualcosa tradotto da un provider di query, sarebbe perfetto. – Servy

+0

Perché stai cercando di evitare l'uso di string.Compare? – tsells

risposta

33

Il confronto delle stringhe con StringComparison.OrdinalIgnoreCase funziona in memoria o con IEnumerable<T>. Stai tentando di usarlo con IQueryable<T>, ma il provider del tuo queryable non lo capisce.

in LINQ to SQL si dovrebbe essere in grado di utilizzare SqlMethods.Like(s.UserName, userName), in questo modo:

var user = db.Users.FirstOrDefault(s => SqlMethods.Like(s.UserName, userName)); 

SqlMethods è nello spazio dei nomi System.Data.Linq.SqlClient.

Il metodo Like non fa distinzione tra maiuscole e minuscole, pertanto è necessario ottenere il risultato previsto.

EDIT : I tried and get "LINQ to Entities does not recognize the method Boolean Like(System.String, System.String) method, and this method cannot be translated into a store expression."

Questo sembra essere un problema noto con EF (link).

This works for me:

db.Users.FirstOrDefault(
    s => s.Username.Equals(username, StringComparison.OrdinalIgnoreCase) 
); 

Sembra che, sebbene EF ha difficoltà a tradurre il statica Equals di SQL, non ha alcun problema a tradurre l'istanza Equals. Questa è una scoperta molto buona - rende una soluzione facile da leggere e performante.

Si potrebbe anche usare un metodo più semplice con ToUpperCase o ToLowerCase, ma che può impedire che ottimizzatori di query da utilizzando indici:

// Warning: this may not perform well. 
var user = db.Users.FirstOrDefault(s => s.UserName.ToUpperCase() == userName.ToUpperCase()); 
+1

Grazie per questo. Ho provato e ottenere "LINQ to Entities" non riconosce il metodo "Boolean Like (System.String, System.String)" e questo metodo non può essere tradotto in un'espressione di archivio. " - pensieri? – SB2055

+0

Questo funziona per me: db.Users.FirstOrDefault (s => s.Username.Equals (username, StringComparison.OrdinalIgnoreCase)); Non so cosa fare in termini di selezione di una risposta - sentitevi liberi di prendere nota di questo e posso controllare il vostro fuori? – SB2055

+0

Diresti che c'è qualcosa di sbagliato nella soluzione che ho postato nel commento? Stavo cercando una soluzione semplice e performante che segua le migliori pratiche. – SB2055

Problemi correlati