【问题标题】:LINQ to SQL PredicateBuilderLINQ to SQL 谓词生成器
【发布时间】:2009-10-27 01:39:55
【问题描述】:

我正在使用 PredicateBuilder,如 http://www.albahari.com/nutshell/predicatebuilder.aspx 所示,一切正常,现在我可以生成 Dynamic 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”迭代器变量,但每次迭代它只获取列表中的最后一个值,就像它通过引用传递一样......

【问题讨论】:

    标签: linq-to-sql predicatebuilder


    【解决方案1】:

    因为 PredicateBuilder 正在构建一个表达式,该表达式将在稍后的时间点执行。当编译器为委托生成闭包时,它会找到在当前范围内创建的任何值,并将它们也携带到闭包中。由于 InstrumentID 是一个值类型 (int),初始化和复制该值意味着每个委托/闭包都将携带该值。如果您不每次都创建该值的副本,则表达式将仅具有对 f.InstrumentID 的字面引用,而不是对其基础值的引用。所以稍后,当表达式被实际执行时,f.InstrumentID 会被计算,它会像上次设置的一样出来,也就是最后一次迭代。

    【讨论】:

    • 这看起来很有趣,我在哪里可以得到这个主题的文档
    【解决方案2】:

    因为它不评估条件,而只是构建表达式。表达式绑定到 foreach 中定义的变量,在整个循环的执行过程中保留它的引用。使用临时变量重新定义它会强制每个表达式使用不同的变量,这会强制它在每次迭代时引用具有值的实例,而不是让所有迭代都引用单个引用并仅具有最后一次迭代的值。

    【讨论】:

    • 谢谢,这有点棘手,它记得我玩数组的时候,并想按值复制它的值.. 头疼,也许简单地说它意味着这是在做值的延迟加载,值随时间变化,并且只有“f”的 1 个瞬间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多