I have a scenario to use codes below to simplify the explanation here.
I have a model class
class Model
{
public string CodeLevel1 { get; set; }
public string CodeLevel2 { get; set; }
public bool IsVoluntary { get; set; }
}
It is obvious that I will build a list of objects
var models = new List<Model>
{
new Model()
{
CodeLevel1 = "32",
CodeLevel2 = "A1",
IsVoluntary = false
},
new Model()
{
CodeLevel1 = "32",
CodeLevel2 = "A2",
IsVoluntary = true
},
new Model()
{
CodeLevel1 = "33",
CodeLevel2 = "A3",
IsVoluntary = true
},
new Model()
{
CodeLevel1 = "34",
CodeLevel2 = "A4",
IsVoluntary = false
},
new Model()
{
CodeLevel1 = "34",
CodeLevel2 = "A5",
IsVoluntary = false
},
new Model()
{
CodeLevel1 = "34",
CodeLevel2 = "A6",
IsVoluntary = true
},
};
I want to use PredicateBuilder introduced in A universal PredicateBuilder to build dynamic query. Following code is just my first step of attempt.
var configs = new Dictionary<string, List<string>>()
{
{ "32", new List<string>() { "A1", "A2"} },
{ "33", new List<string>() { "A3" } },
};
var predicate = PredicateBuilder.False<Model>();
var allLevel1CodesInConfig = (from c in configs select c.Key).ToList();
predicate.Or(x => !allLevel1CodesInConfig.Contains(x.CodeLevel1) && x.IsVoluntary == false);
var filteredList = models.AsQueryable().Where(predicate).ToList();
I get nothing in the filteredList
, but if I rewrite the last line of code I get what I am expecting.
var filteredList = models.AsQueryable().Where(x => !allLevel1CodesInConfig.Contains(x.CodeLevel1) && x.IsVoluntary == false).ToList();
I need some help to understand why the predicate in Where
does not work for me?
The problem is in this line:
predicate.Or(x => !allLevel1CodesInConfig.Contains(x.CodeLevel1) && x.IsVoluntary == false);
Change it to:
predicate = predicate.Or(x => !allLevel1CodesInConfig.Contains(x.CodeLevel1) && x.IsVoluntary == false);
Each PredicateBuilder
method creates a new predicate and does not mutate the original one.