Egal welche Einstellung Sie haben, wenn Sie .ToList()
verwenden, wird es "aufzählbar". Dies ist sehr signifikant, und dieser Satz sollte allgemein bekannt werden.
Wenn .ToList()
verwendet wird, treten viele Dinge auf. Das Aufzählen des Aufzählungsbezeichners bedeutet, dass der vorherige Satz zum Aufzählen des Satzes jetzt verwendet wird, um die Menge tatsächlich zu durchlaufen und die Daten aufzufüllen. Das bedeutet, dass der vorherige Enumerator (der intern als Ausdrucksbaum gespeichert wurde) nun von Entity Framework an Ihre SQLProvider Factory gesendet wird. Dadurch wird das Objektdiagramm aus dem Ausdrucksbaum in SQL konvertiert und die Abfrage auf dem Server ausgeführt, wodurch die Daten zurückgegeben und die Liste aufgefüllt wird.
Lazy laden anstelle von ToList()
wäre, wenn Sie diese IQueryable
aufzählbar hätte, und dann iteriert, dass manuell jedes Element in der Menge oder nur Teilelemente in der Menge geladen.
Sobald Sie die Liste der zurückgegebenen Elemente haben, wird Lazy Loading nur zum Spielen kommen, wenn Navigationseigenschaften vorhanden sind. Wenn es verwandte Eigenschaften gibt, z. B. wenn Sie eine Rechnung haben und die zugehörigen Kundeninformationen aus der Kundentabelle abrufen möchten. Die Beziehung wird nicht explizit zuerst zurückgegeben, nur die Rechnungen. Um also die Kundendaten zu erhalten, könnte man dann (während der Kontext noch offen war, d. H. Nicht entsorgt wurde) über die .Customer
Referenz auf Ihr Objekt zugreifen und es laden. Um umgekehrt alle Kunden während der ursprünglichen Enumeration zu laden, könnten Sie die .Include()
-Funktionalität für Ihre Abfrage verwenden, und dies würde dann der SQL-Provider-Factory mitteilen, eine Verknüpfung zu verwenden, wenn die Abfrage ausgegeben wird.
In Ihrem speziellen Beispiel
List<Students> stdList = Datacontext.Students.ToList();
Dies wird von allen Lehrern und Adressen tatsächlich nicht Last unabhängig davon, ob ein träges Laden aktiviert ist oder nicht. Es lädt nur die Studenten. Wenn Sie ein Lehrer zu faul Last wollen, während die Datacontext ist noch nicht angeordnet sind, können Sie dann verwenden
var firstStudent = stdList.First();
var teacher = firstStudent.Teacher;
//and at this point lazy loading will fetch the teacher
//by issuing **another** query (round trip) to the database
Das wäre nur möglich, wenn ein träges Laden aktiviert waren.
Die Alternative dazu ist zu eifrig Last, die würde die Lehrer und Adressen enthalten. Das würde so aussehen
List<Students> stdList = Datacontext.Students
.Include(s => s.Teacher)
.Include(s => s.Address).ToList();
Und dann später, wenn Sie einen Lehrer des Kontext zuzugreifen versuchen sind entsorgt werden könnte und Zugang wäre noch möglich, weil die Daten bereits geladen wurden.
LazyLoading lädt einfach die Daten, wenn es (in linq Begriffen) gemeint ist, anstatt es auf das Objekt zu laden, egal ob es ausgegeben wird oder nicht. Das obige Beispiel würde Adressen langsam laden, wenn Sie sagten: foreach (var student in stdList) {@ stdList.Address.City}. Im Allgemeinen sollten Sie sich von LazyLoading fernhalten, da dies zu einem n + 1-Szenario führen kann, in dem Sie Ihren Datenbankserver mit Anfragen bombardieren. – BlackjacketMack