我需要通过将文档列表传递给自定义过滤器来过滤文档列表,我正努力使用 foreach
循环动态构建:
var mainPredicate = PredicateBuilder.True<Document>();
// mainPredicate is combined to other filters successfully here ...
var innerPredicate = PredicateBuilder.False<Document>();
foreach (var period in periods)
{
var p = period;
Expression<Func<Document, bool>> inPeriod =
d => d.Date >= p.DateFrom && d.Date <= p.DateTo;
innerPredicate = innerPredicate.Or(d => inPeriod.Invoke(d));
}
mainPredicate = mainPredicate.And(innerPredicate);
最后一行:
documents = this.ObjectSet.AsExpandable().Where(mainPredicate).ToList();
抛出这个异常:
The parameter 'd' was not bound in the specified LINQ to Entities query expression.
任何人都知道为什么我会收到此异常?我不明白传递给 InPeriod 方法的“d”参数在哪里丢失。我不知道这个工作缺少什么。我的代码与许多其他完美运行的示例相同。欢迎提供有关调用表达式及其幕后工作原理的任何其他理论信息。
最佳答案
我不明白你为什么这样做:
innerPredicate = innerPredicate.Or(d => inPeriod.Invoke(d));
当你可以完全避免 Invoke
时,像这样:
innerPredicate = innerPredicate.Or(inPeriod);
这应该工作得很好。
顺便说一句,我感觉 LINQKit 这里有一个错误(除非有一些文档表明它不支持这种情况)。
当我尝试这个类似的代码时:
Expression<Func<int, bool>> first = p1 => p1 > 4;
Expression<Func<int, bool>> second = p2 => p2 < 2;
// Expand is similar to AsExpandable, except it works on
// expressions, not queryables.
var composite = first.Or(d => second.Invoke(d))
.Expand();
...LINQKit 生成了以下复合表达式:
p1 => ((p1 > 4) OrElse (d < 2)) // what on earth is d?
... 确实有未绑定(bind)的参数 d (NodeType = Parameter, Name = 'd').
用 first.Or(second).Expand()
避开 Invoke
生成完全合理的:
p1 => ((p1 > 4) OrElse (p1 < 2)) // much better now...
关于c# - 使用 foreach 循环构建自定义谓词以充当过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16469268/