LINQ to object and universal PredicateBuilder does not seem to play well together

c# expression-trees lambda linq

Question

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?

1
1
7/24/2018 1:52:46 PM

Accepted Answer

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.

2
7/24/2018 1:57:06 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow