15

I have the following code

var returnData = DemoData.Books.AsQueryable();

if (criteria.Author != string.Empty)
{
    returnData = returnData.Where(x => x.Author.Contains(criteria.Author));
}

How do I made the where clause case insensitive?

user2206329
  • 2,792
  • 10
  • 54
  • 81
  • 1
    Possible duplicate of [Case insensitive 'Contains(string)'](http://stackoverflow.com/questions/444798/case-insensitive-containsstring) – Liam Nov 11 '15 at 15:16

2 Answers2

29
  1. You can use ToLower() function. ToLower changes strings to be all lowercase. It converts an entire string—without changing letters that are already lowercased or digits. It copies a string and returns a reference to the new string. So it is always better option to declare criteria.Author.ToLower() outside the query.

    string lowerAuthor = criteria.Author.ToLower();
    returnData = returnData.Where
            (x => x.Author.ToLower().Contains(lowerAuthor));
    
  2. You could also use IndexOfoverload with the StringComparison enum. It would give you better performance than ToLower(). The signature of this overload is:

    int string.IndexOf(string value, StringComparison comparisonType);
    

    returnData = returnData.Where
        (x => x.Author.IndexOf(criteria.Author, StringComparison.CurrentCultureIgnoreCase) != -1);
    
Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
Farhad Jabiyev
  • 26,014
  • 8
  • 72
  • 98
  • 1
    You should declare `criteria.Author.ToLower()` outside the query, to prevent unnecessary string allocation during every iteration (assuming it LINQ to Objects). Or even better - use `IndexOf` with `StringComparison.CurrentCultureIgnoreCase` which will allow you to skip `ToLower` completely. – MarcinJuraszek Apr 13 '14 at 07:47
  • with option 2, where are you saying compare it to x.Author? – user2206329 Apr 14 '14 at 01:47
  • @user2206329 I am searching the beginning index of the `criteria.Author` inside the `x`. And `IndexOf` method returns `-1` if `x` does not contain `criteria.Author`. So, I am looking is th index of `criteria.Author` different from `-1`. – Farhad Jabiyev Apr 14 '14 at 04:22
  • But my question is returnData contains an author property and title property, by doing option 2, is it searching in both the properties for the value of crieria.Author? – user2206329 Apr 14 '14 at 05:06
  • @user2206329 Oh, sorry. I forgot to add `Author` after x. It was giving compile-time error.Now, it is Ok. – Farhad Jabiyev Apr 14 '14 at 05:14
  • You cannot do a case insensitive compare by using `ToLower` because it will fail in Turkish: [Does Your Code Pass The Turkey Test?](http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html) – Kevin Panko Oct 12 '16 at 17:25
6
returnData = returnData.Where
        (x => x.Author.IndexOf(criteria.Author, StringComparison.CurrentCultureIgnoreCase) != -1)

It will make no additional string allocation at all.

I assumed it's LINQ to Objects query.

MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263