如何从多个表达式的并集组成表达式树?
我正在尝试构建一个 IQueryable
,它将由我的实体模型进行评估。我想向它传递两组 lambda,并让它将所有内容组成一个更复杂的表达式树,然后将其传递到数据库以供执行。
这是我到目前为止所得到的:
public class FilterManager<T>
{
public List<Expression<Func<T, bool>>> Inclusive { get; set; }
public List<Expression<Func<T, bool>>> Exclusive { get; set; }
public IQueryable<T> ApplyFilters(IQueryable<T> query)
{
var q = query;
Exclusive.ForEach(exp => q = q.Where(exp)); //works fine
Inclusive.ForEach(exp => /* ??? */);
return q;
}
//ctor, etc.
}
这里的想法是,我将几个表达式添加到 Inclusive
中,将它们“或”在一起。例如,如果 T
是 int
,则代码:
fm.Inclusive.Add(x => x > 1);
fm.Inclusive.Add(y => y < 5);
query = fm.ApplyFilters(query);
应具有与以下内容相同的结果集:
query = query.Where(z => z > 1 || z < 5);
How can I get Inclusive
to work without Third - PredicateBuilder 等第三方工具?第三方工具通常很好,但我想提高对如何在 .NET 中编写表达式的理解。
我还需要确保树不会被评估,以便我可以对数据库进行过滤。这意味着我需要生成 Entity Framework 4.0 可以使用的东西。
I'm trying to construct an IQueryable
which will be evaluated by my entity model. I want to pass it two groups of lambdas and have it compose everything into a more complex expression tree, which is passed on to the database for execution.
Here's what I have so far:
public class FilterManager<T>
{
public List<Expression<Func<T, bool>>> Inclusive { get; set; }
public List<Expression<Func<T, bool>>> Exclusive { get; set; }
public IQueryable<T> ApplyFilters(IQueryable<T> query)
{
var q = query;
Exclusive.ForEach(exp => q = q.Where(exp)); //works fine
Inclusive.ForEach(exp => /* ??? */);
return q;
}
//ctor, etc.
}
The idea here is that I add several Expressions to Inclusive
, which "Ors" them together. For example, if T
is an int
, the code:
fm.Inclusive.Add(x => x > 1);
fm.Inclusive.Add(y => y < 5);
query = fm.ApplyFilters(query);
should have the same result set as:
query = query.Where(z => z > 1 || z < 5);
How can I get Inclusive
to work without third-party tools such as PredicateBuilder? Third-party tools are usually fine, but I'd like to improve my understanding of how to compose expressions in .NET.
I also need to make sure that the tree won't be evaluated yet, so that I can do the filtering on the database. That means I'll need to produce something Entity Framework 4.0 can consume.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试这样的事情吗?
我不确定我没有测试过。
Try something like this?
I'm not sure I haven't tested it.
尽管已经有了一个可接受的答案,但我想指出您可以使用谓词构建器将表达式与
Or
组合起来。这将使其保留为对数据库的简单查询。http://www.albahari.com/nutshell/predicatebuilder.aspx
Even though there's already an accepted answer, I would like to point out you can use predicate builder to combine the expressions with an
Or
. This will keep it as a simple query to the database.http://www.albahari.com/nutshell/predicatebuilder.aspx
我还没有在我的实体模型上测试过它,所以我不知道 EF 是否支持它,但以下内容适用于 L2O。这与 Snowbear JIM-compiler 的代码略有不同:
I haven't tested it on my entity model yet, so I don't know if it will be supported by EF, but the following works for L2O. It's just a slight change from Snowbear JIM-compiler's code:
我能想到的最接近的匹配是这样的:
但我几乎可以肯定这会非常低效
The closest match I can think of is this:
But I'm almost sure that this will be very inefficient