问题
I have the following class:
public class testClass
{
public string name { get; set; }
public int id { get; set; }
public int age { get; set; }
}
and the following code:
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);
My aim is to create a query that returns all records where:
id = 1 and name = "name"
OR
age = 30
So for the query above, it should return the items at index 0, 1, 5
For the above query it does as I want.
However, I now want to the build the predicate by combining a set of queries, rather than explicitly defining them. So I now have the following 2 queries:
var query1 = list.Where(x => x.name == "name" && x.id == 1);
var query2 = list.Where(x => x.age == 30);
and I want to build the query based on the variables query1
and query2
, without explicitly defining the conditions - as these conditions will be dynamically defined and I do not know what they are,and they will be defined in different places.
My guess is I need to do something like this (continuing from above):
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);
but this is not quite correct as the predicate builder will not accept the query as a parameter.
Can this be done?
回答1:
You could create two Predicate<T>
and invoke them in your .Where
call at the end.
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));
Or you could build another Predicate<T>
beforehand and use this
var query = new Predicate<testClass>(x => query1(x) || query2(x));
var predQuery = qble.AsExpandable().Where(query);
来源:https://stackoverflow.com/questions/45962131/c-sharp-predicate-builder-with-using-and-with-or