Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Contains Case Insensitive

Tags:

c#

linq

People also ask

Is Contains case sensitive LINQ?

LINQ StartsWith , EndsWith , and Contains are case sensitive and return false if two same string s are of different cases, e.g., " STRING " and " string ".

Is contains case sensitive in C#?

Contains() method in C# is case sensitive. And there is not StringComparison parameter available similar to Equals() method, which helps to compare case insensitive.

What is Dynamic Linq?

The Dynamic LINQ library exposes a set of extension methods on IQueryable corresponding to the standard LINQ methods at Queryable, and which accept strings in a special syntax instead of expression trees.


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

If the LINQ query is executed in database context, a call to Contains() is mapped to the LIKE operator:

.Where(a => a.Field.Contains("hello")) becomes Field LIKE '%hello%'. The LIKE operator is case insensitive by default, but that can be changed by changing the collation of the column.

If the LINQ query is executed in .NET context, you can use IndexOf(), but that method is not supported in LINQ to SQL.

LINQ to SQL does not support methods that take a CultureInfo as parameter, probably because it can not guarantee that the SQL server handles cultures the same as .NET. This is not completely true, because it does support StartsWith(string, StringComparison).

However, it does not seem to support a method which evaluates to LIKE in LINQ to SQL, and to a case insensitive comparison in .NET, making it impossible to do case insensitive Contains() in a consistent way.


Assuming we're working with strings here, here's another "elegant" solution using IndexOf().

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

The accepted answer here does not mention a fact that if you have a null string ToLower() will throw an exception. The safer way would be to do:

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

Using C# 6.0 (which allows expression bodied functions and null propagation), for LINQ to Objects, it can be done in a single line like this (also checking for null):

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

IndexOf works best in this case

return this
   .ObjectContext
   .FACILITY_ITEM
   .Where(fi => fi.DESCRIPTION.IndexOf(description, StringComparison.OrdinalIgnoreCase)>=0);