2009-10-27 23 views
9

http://www.albahari.com/nutshell/predicatebuilder.aspxのようにPredicateBuilderを使用すると、すべてがうまく動作しますが、今は動的LINQ to SQL式を生成できますが、私が理解できないのはなぜですか?LINQ to SQL PredicateBuilder

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」イテレータ変数を使用しようとするが、それは、参照によって渡されるように、それは唯一の、各反復のためのリストの最後の値を取得する?その一時変数を使用する必要があります...

答えて

10

PredicateBuilderは後で実行される式を構築しているためです。コンパイラがデリゲートのクロージャを生成しているとき、コンパイラは現在のスコープ内で作成された値をすべて見つけ出し、クロージャに渡します。 InstrumentIDは値型(int)なので、値を初期化してコピーすると、各デリゲート/クロージャがその値を保持することを意味します。毎回値のコピーを作成しない場合、式はf.InstrumentIDへのリテラル参照を持ち、その基本値ではありません。後で、式が実際に実行されると、f.InstrumentIDが評価され、最後に設定されたもの(最後の反復)として出力されます。

+0

これはかなり興味深いようですが、このトピックのドキュメントを入手するにはどうすればいいですか – JOBG

2

条件を評価するのではなく、単に式を構築するためです。式はforeachで定義された変数にバインドされ、ループ全体の実行中にその参照が保持されます。それを一時変数で再定義すると、各式は異なる変数を使用します。すべての反復で単一参照を参照し、最後の反復だけの値を持つのではなく、反復ごとに値を持つインスタンスを参照させます。

+0

これはちょっと難しいですが、私が配列で遊んでいた時のことを覚えていて、値によって値をコピーしたいと思います。簡単な言葉で言えば、これは値の遅延ロードを実行していることを意味し、時間の経過とともに値の変化は "f"のほんの一瞬です。 – JOBG