C#谓词构建器:使用AND和OR

6

我有以下类:

public class testClass
{
    public string name { get; set; }
    public int id { get; set; }
    public int age { get; set; }
}

以下是代码:

            var list = new List<testClass>();
            list.Add(new testClass { name = "name", id = 1, age = 30 });
            list.Add(new testClass { name = "name", id = 2, age = 22 });
            list.Add(new testClass { name = "name", id = 3, age = 20 });
            list.Add(new testClass { name = "name", id = 4, age = 30 });
            list.Add(new testClass { name = "name", id = 5, age = 27 });
            list.Add(new testClass { name = "name", id = 6, age = 30 });

            var qble = list.AsQueryable();

            var pred = PredicateBuilder.New<testClass>();
            pred.Or(x => x.name == "name" && x.id == 1);
            pred.Or(x => x.age == 30);
            var predQuery = qble.AsExpandable().Where(pred);

我的目标是创建一个查询,返回所有满足以下条件的记录:

id = 1 and name = "name"

或者

age = 30

对于上述查询,应返回索引0、1、5处的项目。

对于上述查询,它按照我想要的方式执行。

然而,我现在想通过组合一组查询来构建谓词,而不是显式地定义它们。所以现在我有以下两个查询:

var query1 = list.Where(x => x.name == "name" && x.id == 1);
var query2 = list.Where(x => x.age == 30);

我想基于变量query1query2构建查询,而不是明确定义条件-因为这些条件将动态定义,我不知道它们是什么,并且它们将在不同的地方被定义。

我的猜测是我需要像这样做(继续上面的内容):

var qble = list.AsQueryable();

var query1 = list.Where(x => x.name == "name" && x.id == 1);
var query2 = list.Where(x => x.age == 30);

var pred = PredicateBuilder.New<testClass>();
pred.Or(query1);
pred.Or(query2);
var predQuery = qble.AsExpandable().Where(pred);

但这并不完全正确,因为谓词生成器不会接受查询作为参数。

这能做到吗?


需要将查询分开吗? - jonathan.ihm
@jonathan.ihm 我不确定你的意思是什么? - Alex
1
这听起来像是一个xy问题。你实际上想要解决/构建什么?你的“大局观”是什么? - Igor
@Alex 我的意思是,你不能只是做 x.name == "name" && x.id == 1 || x.age == 30 吗? - jonathan.ihm
@jonathan.ihm 不行,因为“and”子句在一个地方被构建,我需要检查更多的条件并将结果组合。 - Alex
显示剩余7条评论
1个回答

4
你可以创建两个Predicate<T>,并在最后的.Where调用中将它们调用。
var qble = list.AsQueryable();

var query1 = new Predicate<testClass>(x => x.name == "name" && x.id == 1);
var query2 = new Predicate<testClass>(x => x.age == 30);

var predQuery = qble.AsExpandable().Where(x => query1(x) || query2(x));

或者您可以预先构建另一个Predicate<T>并使用它

var query = new Predicate<testClass>(x => query1(x) || query2(x));
var predQuery = qble.AsExpandable().Where(query);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接