2010-02-21 4 views
5

Как я могу указать условия в предикатах Where в LINQ, не получая нулевые ссылочные исключения. Например, если q является IQueryable, как может мне нравится:Где предикаты в LINQ

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

var q2 = q.Where(predicate); 

Здесь search является объект, который содержит возможные условия поиска, которые могут или не могут быть установлены как search.CategoryId не может быть установлен, но если это Я хочу получить продукты, установленные этим условием.

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

ответ

7

Вы можете использовать null-coalescing operator??, чтобы заменить возможное значение NULL значением по умолчанию. Следующие наборы пытаются сопоставить 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); 
3

Давайте проанализируем следующую строку:

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 может быть пустым, а это означает, что есть в списке
  • вы перекачиваемой случай search.CategoryId быть nullnull (Nullable<T>)
  • , но, возможно, p.CategoryId (категория, внесенная в список в списке): null (Nullable<T>) - howe верь, я не уверен, что это будет вызывать NullReferenceException
  • q (список/источник) может быть null

Итак: из 5 вариантов вы устранили 1; посмотрите на другие 4? Существует также определенная возможность того, что проблема вызвана чем-то невидимым, не показанным в коде; например, может быть get:

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

и innerObject может быть null; если вы устраните остальные 4 (довольно легко сделать), посмотрите на это в крайнем случае.

Смежные вопросы