C# LINQ中的Where谓词

C# LINQ中的Where谓词,c#,linq,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

如何在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);
表达式谓词=p=>!search.CategoryId.HasValue | |(search.CategoryId.HasValue&&search.CategoryId==p.CategoryId);
var q2=q.Where(谓词);
这里的
search
是一个对象,它包含可能的搜索条件,这些条件可以像search那样设置,也可以不设置。CategoryId可能不设置,但如果设置了,我希望获得由该条件设置的产品

执行此操作时,会出现空引用异常。

您可以使用
??
将可能的空值替换为默认值。以下集合尝试匹配search.Category(如果存在)或仅创建“always true”表达式。这将由任何好的Linq查询提供程序(例如LinqToSql)进行优化

表达式谓词=p=>(search.CategoryId??p.CategoryId)==p.CategoryId);
var q2=q.Where(谓词);
另一种可能是使用动态组合查询谓词。这就是我使用与您使用的模式相似的搜索方式:

var predicate = PredicateBuilder.True<Order>();

if (search.OrderId))
{
   predicate = predicate.And(a => SqlMethods.Like(a.OrderID, search.OderID);  
}
// ...
var results = q.Where(predicate);
var predicate=PredicateBuilder.True();
if(search.OrderId))
{
predicate=predicate.And(a=>SqlMethods.Like(a.OrderID,search.OderID);
}
// ...
var结果=q.Where(谓词);

让我们仔细分析这一行:

Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue
       || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId)
var q2 = q.Where(predicate);
而且
innerObject
可能是
null
;如果您消除了其他4个(非常容易做到),请将这一个视为最后手段

Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue
       || (search.CategoryId.HasValue && search.CategoryId == p.CategoryId)
var q2 = q.Where(predicate);
public int? CategoryId {
    get {return innerObject.CategoryId;}
}