LINQ Contains Case Insensitive

Solution 1:

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

Solution 2:

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.

Solution 3:

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

Solution 4:

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())