LINQ to object和通用PredicateBuilder似乎不能很好地配合

时间:2018-07-24 13:52:46

标签: c# linq lambda expression-trees

我有一种情况,可以在下面使用代码来简化此处的说明。

我有一个模型课

class Model
{
    public string CodeLevel1 { get; set; }
    public string CodeLevel2 { get; set; }
    public bool IsVoluntary { get; set; }
}

很明显,我将建立一个对象列表

        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
            },
        };

我想使用A universal PredicateBuilder中引入的PredicateBuilder来构建动态查询。遵循代码只是我尝试的第一步。

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();

filteredList中我什么也没得到,但是如果我重写最后一行代码,我将得到期望的结果。

var filteredList = models.AsQueryable().Where(x => !allLevel1CodesInConfig.Contains(x.CodeLevel1) && x.IsVoluntary == false).ToList();

我需要一些帮助来了解Where中的谓词为什么对我不起作用?

1 个答案:

答案 0 :(得分:2)

问题出在这一行:

predicate.Or(x => !allLevel1CodesInConfig.Contains(x.CodeLevel1) && x.IsVoluntary == false);

将其更改为:

predicate = predicate.Or(x => !allLevel1CodesInConfig.Contains(x.CodeLevel1) && x.IsVoluntary == false);

每个PredicateBuilder方法都会创建一个新的谓词,并且不会变异原始的谓词。