c# - 使用 foreach 循环构建自定义谓词以充当过滤器

标签 c# linq-to-entities expression-trees linq-expressions linqkit

我需要通过将文档列表传递给自定义过滤器来过滤文档列表,我正努力使用 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/

相关文章:

c# - 更新密码时如何插入日期?

c# - 在运行时创建具有新匿名类型的 lambda 表达式

c# - ASP.Net Core Web API 基于约定的路由?

c# - 信号量异常 - 将指定的计数添加到信号量会导致它超过其最大计数

c# - LINQ to Entities 无法识别该方法

c# - 在 C# 中组合 BinaryExpression 和 Expression<Func<dynamic, bool>>

c# - 使用反射和表达式的自动列映射

c# - 行为未触发 OnPropertyChanged

c# - 访问 JToken 中的所有项目

c# - 从 Javascript 触发回发失败