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 benull
p
could be null, meaning there is anull
in the list- you've handled the case of
search.CategoryId
beingnull
(Nullable<T>
) - but maybe
p.CategoryId
(the category on a record in the list) isnull
(Nullable<T>
) - however, I'm not sure that this would cause aNullReferenceException
q
(the list / source) could benull
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.