LINQ to SQL的PredicateBuilder(LINQ to SQL Predicate

2019-09-01 09:18发布

使用PredicateBuilder这里看到林http://www.albahari.com/nutshell/predicatebuilder.aspx ,一切都很正常,现在我可以genrate动态的LINQ to SQL表达式,但我不明白的是,为什么当我在这样一个循环:

var inner = PredicateBuilder.False<MyType>();
foreach (var f in Filtermodel.InstrumentsFilterList.Where(s => s.isActive))
        {
          int temp = f.InstrumentID;
          inner = inner.Or(ud => ud.InstrumentId == temp);
        }

为什么我必须使用临时变量?我尝试使用了“F”迭代变量,但它只能获得名单上的最后一个值对于每次迭代,就像是按引用传递...

Answer 1:

因为PredicateBuilder正在建立,这将在稍后的时间点被执行的表达式。 当编译器产生用于代表关闭,它发现它在当前范围产生的任何值,并且将它们携带到闭合为好。 由于InstrumentID是值类型(INT),初始化和复制值意味着每个代表/关闭将携带该值与它。 如果你不每次都创造价值的一个副本,表达只会有文字提及f.InstrumentID,而不是它的潜在价值。 所以后来,当实际执行的表达,f.InstrumentID进行评估,它会出来的不管它上一次的设置,这是最后一次迭代。



Answer 2:

因为它不是评估的条件,而只是建设的表达。 表达结合在foreach定义的变量,它保留它的整个循环的执行参考。 用临时变量力重新定义它的每个表达式中使用一个不同的变量,这迫使它来指该实例与所述值在每一次迭代,而不是具有所有迭代参考单一参考和具有只是最后一次迭代的值。



文章来源: LINQ to SQL PredicateBuilder