LINQ中的谓词

时间:2010-02-21 09:23:03

标签: c# linq

如何在LINQ中的Where谓词中指定条件而不会获得空引用异常。例如,如果q是IQueryable,我该怎么做:

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

var q2 = q.Where(predicate);

此处search是一个对象,其中包含可能或不可能设置的搜索条件,如search.CategoryId可能未设置但如果是,我想获取由该条件设置的产品。< / p>

当我这样做时,我得到空引用异常。

2 个答案:

答案 0 :(得分:7)

您可以使用null-coalescing operator ??将可能的空值替换为默认值。以下集合尝试匹配search.Category(如果存在)或仅创建“始终为true”表达式。这将由任何优秀的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);

答案 1 :(得分: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可以为null,表示列表中有null
  • 您已处理 search.CategoryId null Nullable<T>p.CategoryId
  • 的情况
  • 但是null(列表中记录的类别)可能是Nullable<T>NullReferenceException) - 但是,我不确定这会导致{{1} }
  • q(列表/来源)可以是null

所以:你已经淘汰的5个选项中有1个;看看其他4? 有明确的可能性,问题是由代码中未显示的不可见的东西引起的;例如get可以是:

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

innerObject可以是null;如果你消除了其他的4(很容易做到),那就把它作为最后的手段。