2015-05-14 121 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循环中获得答案,并且不会花费太多时间。