C# LINQ 中的 Where 谓词
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2305438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Where Predicates in LINQ
提问by JustAProgrammer
How can I specify conditions in Where predicates in LINQ without getting null reference exceptions. For instance, if q
is an IQueryable how can I do like:
如何在 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);
Here search
is an object that holds possible search conditions that may or may not be set like search.CategoryId might not be set but if it is I want to get the products that are set by that condition.
这search
是一个保存可能的搜索条件的对象,这些条件可能会或可能不会像 search.CategoryId 那样设置,但如果是这样,我想获取由该条件设置的产品。
When I do this I get null reference exceptions.
当我这样做时,我得到空引用异常。
采纳答案by Johannes Rudolph
You can use the null-coalescing operator??
to replace a possible null value with a default value. The following sets tries to match the search.Category if it exists or simply creates an "always true" expression. This will be optimized by any good Linq query provider (e.g. LinqToSql).
您可以使用空合并运算符??
将可能的空值替换为默认值。以下集合尝试匹配 search.Category 如果它存在或只是创建一个“始终为真”的表达式。这将由任何好的 Linq 查询提供程序(例如 LinqToSql)进行优化。
Expression<Func<ProductEntity,bool>> predicate = p => (search.CategoryId ?? p.CategoryId) == p.CategoryId);
var q2 = q.Where(predicate);
Another possibility would be to dynamically compose a query predicate using PredicateBuilder. That's the way I do it for searches with a similar pattern as you use:
另一种可能性是使用PredicateBuilder动态组合查询谓词。这就是我使用与您使用的模式类似的搜索方式进行的搜索:
var predicate = PredicateBuilder.True<Order>();
if (search.OrderId))
{
predicate = predicate.And(a => SqlMethods.Like(a.OrderID, search.OderID);
}
// ...
var results = q.Where(predicate);
回答by Marc Gravell
Let's dissect the line:
让我们剖析一下这条线:
Expression<Func<ProductEntity,bool> predicate = p => !search.CategoryId.HasValue
|| (search.CategoryId.HasValue && search.CategoryId == p.CategoryId)
var q2 = q.Where(predicate);
So how many ways can we get null
problems?
那么我们有多少种方式会遇到null
问题呢?
search
(your "captured" variable) could benull
p
could be null, meaning there is anull
in the list- you've handledthe case of
search.CategoryId
beingnull
(Nullable<T>
) - but maybe
p.CategoryId
(the category on a record in the list) isnull
(Nullable<T>
) - however, I'm not sure that this would cause aNullReferenceException
q
(the list / source) could benull
search
(您的“捕获”变量)可能是null
p
可能为空,意味着null
列表中有一个- 你处理的情况下
search.CategoryId
是null
(Nullable<T>
) - 但也许
p.CategoryId
(列表中记录的类别)是null
(Nullable<T>
) - 但是,我不确定这会导致NullReferenceException
q
(列表/来源)可能是null
So: out of 5 options you've eliminated 1; look at the other 4? There is alsothe definite possibility that the issue is caused by something invisible not shown in the code; for example the get
could be:
所以:在 5 个选项中你已经消除了 1 个;看看其他4个?有也了一定的可能性问题是由代码未显示看不见的东西造成的; 例如get
可能是:
public int? CategoryId {
get {return innerObject.CategoryId;}
}
and innerObject
could be null
; if you eliminate the other 4 (pretty easy to do), look at at this one as a last resort.
并且innerObject
可能是null
;如果您消除其他 4 个(很容易做到),请将此作为最后的手段。