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