Ich versuche, Code neu zu gestalten, der in letzter Zeit sehr langsam geworden ist, und ich stieß auf einen Codeblock, der mehr als 5 Sekunden für die Ausführung benötigt.Entity Framework + LINQ + "Enthält" == Super Slow?
Der Code besteht aus zwei Aussagen:
IEnumerable<int> StudentIds = _entities.Filters
.Where(x => x.TeacherId == Profile.TeacherId.Value && x.StudentId != null)
.Select(x => x.StudentId)
.Distinct<int>();
und
_entities.StudentClassrooms
.Include("ClassroomTerm.Classroom.School.District")
.Include("ClassroomTerm.Teacher.Profile")
.Include("Student")
.Where(x => StudentIds.Contains(x.StudentId)
&& x.ClassroomTerm.IsActive
&& x.ClassroomTerm.Classroom.IsActive
&& x.ClassroomTerm.Classroom.School.IsActive
&& x.ClassroomTerm.Classroom.School.District.IsActive).AsQueryable<StudentClassroom>();
So ist es ein bisschen chaotisch, aber zuerst bekomme ich eine Distinct Liste von IDs aus einer Tabelle (Filter), dann ich abfragen eine andere Tabelle, die es benutzt.
Dies sind relativ kleine Tabellen, aber es ist immer noch 5+ Sekunden Abfragezeit.
Ich legte dies in LINQPad und es zeigte, dass es zuerst die untere Abfrage und dann 1000 "distinct" Abfragen später ausgeführt wurde.
Aus einer Laune heraus änderte ich den "StudentIds" -Code, indem ich am Ende nur .ToArray() hinzufügte. Dies hat die Geschwindigkeit 1000x verbessert ... es dauert jetzt 100ms, um die gleiche Abfrage zu vervollständigen.
Was ist das Geschäft? Was mache ich falsch?
'Was mache ich falsch?' Ähm ... macht StudentID nicht zu einem Array? :) –
In anderen Nachrichten, ist Linqpad nicht ein cooles Werkzeug? –
Dies ist einer der Fälle, in denen "var" den Code magisch schneller gemacht hätte, indem festgestellt wurde, dass StudentIds IQueryable sein könnten. –