Linq to Entities : using ToLower() on NText fields

Never use .ToLower() to perform a case-insensitive comparison. Here’s why:

  1. It’s possibly wrong (your client collation could be, say, Turkish, and your DB collation not).
  2. It’s highly inefficient; the SQL Emitted is LOWER instead of = with a case-insensitive collation.

Instead, use StringComparison.OrdinalIgnoreCase or StringComparison.CurrentCultureIgnoreCase:

var q = from f in Context.Foos
        where f.Bar.Equals("hi", StringComparison.OrdinalIgnoreCase)
        select f;

But for Contains() there’s a problem: Unlike Equals, StartsWith, etc., it doesn’t have an overload for a StringComparison argument. Why? Good question; ask Microsoft.

That, combined with SQL Server’s limitation on LOWER means there’s no simple way to do what you want.

Possible workarounds might include:

  • Use a full text index, and do the search in a procedure.
  • Use Equals or StartsWith instead, if possible for your task
  • Change the default collation of the column?

Leave a Comment