Где предикаты в LINQ

Как я могу указать условия в Где предикаты в 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 не мог бы быть установлен, но если это, я хочу получить продукты, которые установлены тем условием.

Когда я делаю это, я получаю исключения нулевой ссылки.

6
задан JustAProgrammer 21 February 2010 в 09:23
поделиться

2 ответа

Вы можете использовать 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);
7
ответ дан 10 December 2019 в 00:37
поделиться

Препарируем строку:

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 варианта (это довольно легко сделать), посмотрите на этот, как на последнее средство.

3
ответ дан 10 December 2019 в 00:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: