2012-04-10 95 views
1

我有這樣的LinQ:如何使用LINQ來提高性能

var IPI = item.INV_TAXES.Where(t => t.TAXTYPES.TAXNAME == "IPI") 
         .Select(t => new {TOT_AMT = t.TAXVALUE, t.TAXFACTOR, t.TAXBASE}) 
         .First(); 

然後後的代碼我稱之爲下一行約10倍:

PerformSomeCalculation(IPI.TOT_AMT); 
PerformAnotherStuff(IPI.TOT_AMT,IPI.TAXVALUE); 
PerformSomethingElse(IPI.TAXBASE); 

我不知道每次我打電話每個IPI成員,LinQ都執行或者只是第一次分配它時?

將IPI成員首先分配給變量是否更好?

decimal IPI_TOT_AMT = IPI.TOT_AMT, 
     IPI_TAXVALUE = IPI.TAXVALUE, 
     IPI_TAXBASE = IPI.TAXBASE; 

然後使用它們。

感謝您的所有建議。

回答

7

首先,不要喊了,在你的代碼沒有被執行了。

你是對的關心。 A 查詢執行新鮮每次您訪問它,因爲結果可能會改變。但First的結果不是查詢,而是一個值。

也就是說,如果你這樣做:

var query = whatever.Where(whatever).Select(whatever); 
Console.WriteLine(query.First()); 
Console.WriteLine(query.First()); 

則查詢第一線,第二線執行創建由第三線再次執行。查詢不知道第二次調用First時第一個結果是否不同,因此它再次運行查詢。

相反,如果你這樣做:

var query = whatever.Where(whatever).Select(whatever); 
var first = query.First(); 
Console.WriteLine(first); 
Console.WriteLine(first); 

然後第一行創建查詢,第二行執行查詢,並將結果存儲,以及第三和第四行報告所存儲的結果。

+0

我不喜歡在代碼中喊出來,但這是一個愚蠢的要求,那些大寫字母的屬性和變量,對此抱歉。 – doc 2012-04-10 22:32:23

4

在您提供的代碼中,僅當您調用.First()方法時纔會運行LINQ查詢。

通過在訪問變量前將成員賦值給變量,不會有明顯的性能改進。

請注意,所有LINQ語句並不總是這種情況。例如,如果你曾說過:

var IPIs = item.INV_TAXES.Where(t => t.TAXTYPES.TAXNAME == "IPI") 
        .Select(t => new {TOT_AMT = t.TAXVALUE, t.TAXFACTOR, t.TAXBASE}); 

...,然後傳遞到的IPI幾種方法,你可能會用不同的數據庫往返結束。爲了避免這個問題,您可以在分配變量之前調用.ToList()以強制立即進行評估。但在這種情況下,調用.First()有效地做同樣的事情。

1

如果我每次打電話給IPI的每個成員時,我都會發現LinQ 每次都執行還是第一次執行它時?

否,則查詢時,才執行一次 - IPI是匿名類型的實例與一羣基本屬性的(小數實際上)。此對象不再與查詢連接 - 由於First()擴展方法強制立即執行並返回輸入集合中的第一個項目,因此執行了查詢並返回了此對象。

0

First()方法執行linq查詢並返回第一個對象 此對象的類型與您使用的任何其他對象類似,唯一的區別是類定義由編譯器編寫。

所以當你使用對象