LINQ contiene maiuscole e minuscole

Questo codice è case sensitive, come renderlo case insensitive?

public IQueryable GetFacilityItemRootByDescription(string description) { return this.ObjectContext.FACILITY_ITEM.Where(fi => fi.DESCRIPTION.Contains(description)); } 

 fi => fi.DESCRIPTION.ToLower().Contains(description.ToLower()) 

Se la query LINQ viene eseguita nel contesto del database, una chiamata a Contains() viene mappata all’operatore LIKE :

.Where(a => a.Field.Contains("hello")) diventa Field LIKE '%hello%' . L’operatore LIKE non fa distinzione tra maiuscole e minuscole per impostazione predefinita, ma può essere modificato cambiando le regole di confronto della colonna .

Se la query LINQ viene eseguita nel contesto .NET, è ansible utilizzare IndexOf () , ma tale metodo non è supportato in LINQ to SQL.

LINQ to SQL non supporta i metodi che prendono come parametro un parametro CultureInfo, probabilmente perché non può garantire che il server SQL gestisca le culture allo stesso modo di .NET. Questo non è completamente vero, perché supporta StartsWith(string, StringComparison) .

Tuttavia, non sembra supportare un metodo che valuti come LIKE in LINQ to SQL e un confronto senza distinzione tra maiuscole e minuscole in .NET, rendendo imansible fare case sensitive Contains () in modo coerente.

Supponendo che stiamo lavorando con le stringhe qui, ecco un’altra soluzione “elegante” che utilizza IndexOf() .

 public IQueryable GetFacilityItemRootByDescription(string description) { return this.ObjectContext.FACILITY_ITEM .Where(fi => fi.DESCRIPTION .IndexOf(description, StringComparison.OrdinalIgnoreCase) != -1); } 

La risposta accettata qui non menziona il fatto che se si dispone di una stringa null ToLower () genererà un’eccezione. Il modo più sicuro sarebbe quello di fare:

 fi => (fi.DESCRIPTION ?? string.Empty).ToLower().Contains((description ?? string.Empty).ToLower()) 

Usando C # 6.0 (che consente funzioni con espressione e propagazione nulla), per LINQ to Objects, può essere fatto in una singola riga come questa (controllando anche per null):

 public static bool ContainsInsensitive(this string str, string value) => str?.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0; 

Puoi usare string.Compare

  lst.Where(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0); 

se vuoi solo controllare contiene quindi usa “Qualsiasi”

  lst.Any(x => string.Compare(x,"valueToCompare",StringComparison.InvariantCultureIgnoreCase)==0) 

IndexOf funziona meglio in questo caso

 return this .ObjectContext .FACILITY_ITEM .Where(fi => fi.DESCRIPTION.IndexOf(description, StringComparison.OrdinalIgnoreCase)>=0); 
 public static bool Contains(this string input, string findMe, StringComparison comparisonType) { return String.IsNullOrWhiteSpace(input) ? false : input.IndexOf(findMe, comparisonType) > -1; } 

Utilizzare il metodo Enumerable.Contains (IEnumerable, TSource, IEqualityComparer) , utilizzando uno dei comparatori StringComparer .___ IgnoreCase (O Ordinal, InvariantCulture o CurrentCulture).

 public IQueryable GetFacilityItemRootByDescription(string description) { return this.ObjectContext.FACILITY_ITEM.Where( fi => fi.DESCRIPTION.Contains(description, StringComparer.OrdinalIgnoreCase) ); } 

Utilizzare il metodo String.Equals

 public IQueryable GetFacilityItemRootByDescription(string description) { return this.ObjectContext.FACILITY_ITEM .Where(fi => fi.DESCRIPTION .Equals(description, StringComparison.OrdinalIgnoreCase)); }