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();

私が今やっていることは、ループ内で 1 つずつ取得する代わりに、使用するレコードを取得することです。これは良い習慣ですか?時々、私は良い仕事をしていないと思います:(

レコードを取得したら、それをメモリに保存し、LINQ TO OBJECTS (メモリから) を使用して記録します。

4

1 に答える 1

0

そのため、データベースへの呼び出しは常に遅くなることを覚えておいてください。実際、多くのアプリケーションで最も遅い部分です。したがって、アイテムを 1 つずつ取得しようとするのではなく、一度に多くのアイテムを返すように努力する必要があります。

必要な情報を一度にできるだけ多く返すようにクエリを書き直すようにしてください。より多くのメモリを使用する可能性がありますが、多くの場合、時間の節約にはそれほど価値がありません。データベースへの接続が遅い!

第二に、(最後にチェックした)Entity Frameworkはリフレクションを使用して、オブジェクトにプロパティを設定できるようにします。リフレクションも非常に遅いため、EF のクールな要素にもかかわらず、私は依然として手動でクエリを実行することを好みます。パフォーマンスは大幅に高速化されています (ただし、1 つの言語 (C#) だけでなく、概念的に非常に異なる 2 つの言語 (C# と SQL) を扱っているため、もちろん別の複雑なレイヤーが導入されます)。

于 2013-05-15T16:58:55.890 に答える