2009-10-27 126 views
9

我在這裏看到使用PredicateBuilder http://www.albahari.com/nutshell/predicatebuilder.aspx,一切都很好,現在我可以創建動態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 2009-10-27 03:53:10

2

因爲它不評估條件,而只是構建表達式。該表達式綁定到foreach中定義的變量,該變量在整個循環的執行過程中保留它的引用。用臨時變量重新定義它會強制每個表達式使用一個不同的變量,這會強制它在每次迭代時使用值引用實例,而不是使所有迭代都引用單個引用並使其值僅爲最後一次迭代。

+0

謝謝,這有點棘手,它記得我玩數組的時間,並希望通過值複製它的值..頭痛,也許簡單地說,這意味着這是對數值進行延遲加載,隨着時間的推移而變化,並且這僅僅是「f」的1個實例。 – JOBG 2009-10-27 03:58:46