Where Predicates in LINQ

You can use the null-coalescing operator ?? to replace a possible null value with a default value. The following sets tries to match the search.Category if it exists or simply creates an "always true" expression. This will be optimized by any good Linq query provider (e.g. LinqToSql).

Expression<Func<ProductEntity,bool>> predicate = p => (search.CategoryId ?? p.CategoryId) == p.CategoryId);

var q2 = q.Where(predicate);

Another possibility would be to dynamically compose a query predicate using PredicateBuilder. That's the way I do it for searches with a similar pattern as you use:

var predicate = PredicateBuilder.True<Order>();

if (search.OrderId))
{
   predicate = predicate.And(a => SqlMethods.Like(a.OrderID, search.OderID);  
}
// ...
var results = q.Where(predicate);

Let's dissect the line:

Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue
       || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId)
var q2 = q.Where(predicate);

So how many ways can we get null problems?

  • search (your "captured" variable) could be null
  • p could be null, meaning there is a null in the list
  • you've handled the case of search.CategoryId being null (Nullable<T>)
  • but maybe p.CategoryId (the category on a record in the list) is null (Nullable<T>) - however, I'm not sure that this would cause a NullReferenceException
  • q (the list / source) could be null

So: out of 5 options you've eliminated 1; look at the other 4? There is also the definite possibility that the issue is caused by something invisible not shown in the code; for example the get could be:

public int? CategoryId {
    get {return innerObject.CategoryId;}
}

and innerObject could be null; if you eliminate the other 4 (pretty easy to do), look at at this one as a last resort.

Tags:

C#

Linq