2015-05-14 88 views
1

我正在使用foreach循環來計算問題的答案。如何提高foreach循環的性能

它會針對一個問題計算所有答案,但是當它加載下一個問題時,每次只需要一分鐘。我該如何縮短這個時間?

List<Questionnaire> myQuestionnaires = report.Project 
              .Questionnaires 
              .Where(q => q.Active) 
              .ToList<Questionnaire>();   

foreach (Questionnaire q in myQuestionnaires) 
{ 
    foreach (ItemAnswer a in q.Answers) 
    { 
     //possible answers 
    } 
}     
+5

這裏的for-each循環正在處理內存中的集合,所以它應該很快!當你調用.ToList()方法時,你確定延遲不在提取問題嗎?你的數據存儲是什麼?你有多少結果回來? – olitee

+1

這裏根本沒有必要使用'.ToList',它使你迭代集合兩次。只需用'var'替換頂部的'List '並在末尾刪除'ToList'。 –

+0

數據存儲在MySQL上,結果超過200個問題 –

回答

2

我會做的不是使用.ToList()或.AsEnumerable()。這兩個函數將執行由您的linq語句生成的T-SQL並將所有記錄提取到內存中。

更好的選擇是繼續使用linq來用謂詞過濾結果。

var query = report.Project 
        .Questionnaires 
        .Where(q => q.Active && q.Answers == /*some condition*/) 

var query = report.Project 
        .Questionnaires 
        .Where(q => q.Active) 
        .Select(q => q.Answers) // Select the answers only 
        .Where(answers => answers.Property == /* some condition */) 

然後,一旦你完成你的過濾記錄,調用.ToList()或.AsEnumerable()讀取結果時。

這使您可以使用數據庫來完成所有工作,而不是將集合拉入內存並迭代。

1

這似乎是延遲加載的問題,因爲LINQ默認啓用延遲加載。在你的代碼部分,它會加載所有的答案(沒有任何連接)從數據庫爲每個問題。

您可以通過使用

report.DeferredLoadingEnabled=false; 

現在你寫的代碼得到的答案一些額外的線,因爲現在「q.Answers」會不會是具有數據控制的數據上下文級別延遲加載。你可以編寫另一個Linq在第一個foreach循環中獲得答案,並且不會花費太多時間。