0

有時,當我使用LINQ編寫查詢時,如果我在循環中使用它。它的表現變慢。實體框架中的性能

 var query1 = from c in db.Classes 
        where c.TeacherId.Equals(teacherId) 
        select c; 

     // AnsweredAssignment Query 
     var query2 = (from c in db.AnsweredAssignments 
         where c.AssignmentId == assignmentId && c.Student.Class.TeacherId.Equals(teacherId) 
         select c).ToArray(); 

     // Tokens Query 
     var query3 = (from c in db.Tokens 
         where c.AssignmentId == assignmentId && c.Student.Class.TeacherId.Equals(teacherId) 
         select c).ToArray(); 

     // OverwrittenScores Query 
     var query4 = (from os in db.OverwrittenScores 
         where os.AssignmentId == assignmentId && os.Student.Class.TeacherId.Equals(teacherId) 
         select os).ToArray(); 



     foreach (var c in query1) 
     { 
      foreach (var s in c.Students) 
      { 
       var aaItems = (from aa in query2 
           where aa.StudentId == s.StudentId 
           select aa).ToArray(); 


       // Generate scores for objectives 
       var id3 = (from aa in aaItems 
          where !aa.IsMakeup 
          orderby aa.Score descending 
          select aa).FirstOrDefault(); 

       if (id3 != null) 
       { 
        var aa3 = (from aa in query2 
           where aa.AnsweredAssignmentId == id3.AnsweredAssignmentId 
           select aa).SingleOrDefault(); 
        ... 
       } 


       var tokens = (from t in query3 
           where t.StudentId == s.StudentId 
           select new MonitorByGeneralScoreToAnsweredAssignment(AssignmentStatus.Pending)).ToList(); 

       ... 


       // does exist any overwritten score? 
       var osItem = query4.Where(os => os.StudentId == s.StudentId).SingleOrDefault(); 

       ... 
      } 

     // OverwrittenScores Query 
     var query4 = (from os in db.OverwrittenScores 
         where os.AssignmentId == assignmentId && os.Student.Class.TeacherId.Equals(teacherId) 
         select os).ToArray(); 

我現在正在做的是得到我要使用的記錄,而不是一個接一個在循環內部。這是一個很好的做法嗎?有時候我想,我沒有做一個良好的工作:(

當我有記錄,我已經將它保存到內存中,並使用LINQ to對象(從內存中)我得到記錄。

回答

0

所以請記住,調用數據庫總是很慢,事實上,它通常是大多數應用程序中最慢的部分,因此,你應該努力一次返回很多東西,而不是一次一個地獲取項目

努力重寫您的查詢,以便您根據需要儘可能多地返回雖然您可能需要更多的內存,但通常不值得節省時間。連接到數據庫很慢!其次,(最後我檢查)實體框架使用反射能夠設置對象的屬性。反思也非常緩慢,這就是爲什麼 - 儘管EFs很酷的因素 - 我仍然喜歡親自去查詢。性能要快得多(但當然會引入另一層複雜性,因爲現在你不僅要處理一種語言 - C# - 而且還有兩種 - C#和SQL - 它們在概念上有很大不同)。