4

I am attempting to write an expression for an advanced search. However, I need to check if each property is null, otherwise an error will be thrown.

I have included the expression without the null checking below.

The result is output using jQuery dataTables.

filteredPeople = unitOfWork.PeopleRepository.Get().Where(c =>
   IdSearchable && c.personID.ToString().Contains(param.sSearch.ToLower())
   || surnameSearchable && c.Surname.ToLower().Contains(param.sSearch.ToLower())
   || firstNameSearchable && c.FirstName.ToLower().Contains(param.sSearch.ToLower())
   || genderSearchable && c.Gender.ToLower().Contains(param.sSearch.ToLower())
));
Raidri
  • 17,258
  • 9
  • 62
  • 65
jjc99
  • 3,559
  • 4
  • 22
  • 21
  • 3
    So what have you tried to check for null? (And given the combinations of && and || you've got there, I'd start explicitly bracketing them...) – Jon Skeet Mar 14 '13 at 10:30
  • Which properties do you mean to check, and what will you do if they are null? note that the `c.Surname` etc will presumably be handled by an ORM via SQL, so aren't actually tested in C# code. Or is this all LINQ-to-Objects? – Marc Gravell Mar 14 '13 at 10:30
  • @jc99 observation: since you're coming here to ask for help, it would be to your advantage to answer questions asking for necessary context for *providing* the correct information – Marc Gravell Mar 14 '13 at 10:58

2 Answers2

7

Try below, I basically wrapped all your individual conditional checks inside brackets to further aid both readability and to make sure you don't get any weird results with the compilers interpretation of that huge logic.

filteredPeople = unitOfWork.PeopleRepository.Get()
                .Where(c => (IdSearchable
                        && c.personID != null
                        && c.personID.ToString().Contains(param.sSearch.ToLower()))
                    || (surnameSearchable 
                        && c.Surname != null
                        && c.Surname.ToLower().Contains(param.sSearch.ToLower()))
                    || (firstNameSearchable 
                        && c.FirstName != null
                        && c.FirstName.ToLower().Contains(param.sSearch.ToLower()))
                    || (genderSearchable 
                        && c.Gender != null
                        && c.Gender.ToLower().Contains(param.sSearch.ToLower())));
Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
1

Try this:

filteredPeople = unitOfWork.PeopleRepository.Get()
                .Where(c => (IdSearchable
                     && c.personID != null
                     && c.personID.ToString().Contains(param.sSearch.ToLower()))
                   ||
                     ....

From MSDN

The conditional-AND operator (&&) performs a logical-AND of its bool operands, but only evaluates its second operand if necessary.

Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68
  • Personally, I would expect this PeopleRepository.Get() to be using some kind of ORM tooling, in which case this isn't actually going to be executing as .NET *anyway*; I wonder if this is only an issue with a testing mock – Marc Gravell Mar 14 '13 at 10:34