Как я могу указать условия в Где предикаты в LINQ, не получая исключения нулевой ссылки. Например, если q
IQueryable, как может я действительно любить:
Expression<Func<ProductEntity,bool>> predicate = p => !search.CategoryId.HasValue || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId);
var q2 = q.Where(predicate);
Здесь search
объект, который содержит возможные условия поиска, которые могут или не могут быть установлены как поиск. CategoryId не мог бы быть установлен, но если это, я хочу получить продукты, которые установлены тем условием.
Когда я делаю это, я получаю исключения нулевой ссылки.
Вы можете использовать null-coalescing operator (?)
для замены возможного нулевого значения значением по умолчанию. Следующий набор пытается соответствовать search.Category, если он существует, или просто создает выражение "всегда верно". Это будет оптимизировано любым хорошим поставщиком запросов Linq (например, LinqToSql).
Expression<Func<ProductEntity,bool>> predicate = p => (search.CategoryId ?? p.CategoryId) == p.CategoryId);
var q2 = q.Where(predicate);
Другой возможностью может быть динамическое составление предиката запроса с помощью PredicateBuilder. Вот как я это делаю для поиска с похожим шаблоном, как у вас:
var predicate = PredicateBuilder.True<Order>();
if (search.OrderId))
{
predicate = predicate.And(a => SqlMethods.Like(a.OrderID, search.OderID);
}
// ...
var results = q.Where(predicate);
Препарируем строку:
Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue
|| (search.CategoryId.HasValue && search.CategoryId == p.CategoryId)
var q2 = q.Where(predicate);
Итак, сколькими способами мы можем получить null
проблемы?
search
(ваша "захваченная" переменная) может быть null
p
может быть null, то есть в списке есть null
search. CategoryId
быть null
(Nullable
)p. CategoryId
(категория на записи в списке) является null
(Nullable
) - однако, я не уверен, что это вызовет NullReferenceException
q
(список / источник) может быть null
Итак: из 5 вариантов вы исключили 1; посмотрите на остальные 4? Существует также определенная возможность, что проблема вызвана чем-то невидимым, не показанным в коде; например, get
может быть:
public int? CategoryId {
get {return innerObject.CategoryId;}
}
и innerObject
может быть null
; если вы исключите остальные 4 варианта (это довольно легко сделать), посмотрите на этот, как на последнее средство.