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

Ale*_*lex 5 c# linq predicatebuilder

我有以下课程:

public class testClass
{
    public string name { get; set; }
    public int id { get; set; }
    public int age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以及以下代码:

            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);
Run Code Online (Sandbox Code Playgroud)

我的目标是创建一个查询,返回所有记录,其中:

id = 1 and name = "name"
Run Code Online (Sandbox Code Playgroud)

或者

age = 30
Run Code Online (Sandbox Code Playgroud)

所以对于上面的查询,它应该返回索引 0、1、5 处的项目

对于上面的查询,它按我的意愿行事。

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

var query1 = list.Where(x => x.name == "name" && x.id == 1);
var query2 = list.Where(x => x.age == 30);
Run Code Online (Sandbox Code Playgroud)

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

我的猜测是我需要做这样的事情(从上面继续):

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);
Run Code Online (Sandbox Code Playgroud)

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

这能做到吗?

Phi*_*aré 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));
Run Code Online (Sandbox Code Playgroud)

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

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