Search code examples
c#linqshort-circuiting

Performing a LINQ query with optional search clauses


I have a page where you can search for people. They can either get a list of all people, or filter it by certain criteria such as first or last name.

So far, I have been trying trying to use the technique detailed in this question.

So my code looks like

string firstname=...
string lastname=...

var people=from p in People.All()
           where (firstname==null || firstname.ToLower()==p.FirstName.ToLower()) &&
                 (lastname==null || lastname.ToLower()==p.LastName.ToLower())
           select p;

I get a null reference error when building the query however when both firstname and lastname is null. Removing the where clause gets rid of the error.

Why would this not work? Does C# try to evaluate the second part of each part of the where clause? It shouldn't because of the short-circuited OR right?


Solution

  • Use string.Equals:

    from p in People.All()
    where (firstname == null || string.Equals (firstname, p.FirstName, StringComparison.InvariantCultureIgnoreCase)) &&
          (lastname == null || string.Equals (lastname, p.LastName, StringComparison.InvariantCultureIgnoreCase))
    select p
    

    Not only does this avoid the null problem, but it forces you to specify a string comparison type (a good thing). In other words, you specify whether to use rules specific to the local or invariant culture when performing the case-insensitive comparison.