EF: Lazy Loading, Eager Loading und "Enumerable aufzählen"
Ich finde, ich bin verwirrt über lazy loading, usw.
Ersten, sind diese beiden Aussagen äquivalent:
(1) Lazy loading:
_flaggedDates = context.FlaggedDates.Include("scheduledSchools")
.Include ("interviews").Include("partialDayAvailableBlocks")
.Include("visit").Include("events");
(2) Eager loading:
_flaggedDates = context.FlaggedDates;
In anderen Worten, in (1) "Includes" bewirken, dass die navigation Sammlungen/Eigenschaften geladen werden zusammen mit den spezifischen Sammlung angefordert, unabhängig von der Tatsache, dass Sie mit lazy loading ... richtig?
Und in (2), die Anweisung " load all der navigation Entitäten, auch wenn Sie nicht speziell anfordern, weil Sie mit eager loading ... richtig?
Zweitens: selbst wenn Sie mit eager loading werden die Daten nicht tatsächlich heruntergeladen werden, aus der Datenbank, bis Sie "aufzählen, die enumerable", wie im folgenden code:
var dates = from d in _flaggedDates
where d.dateID = 2
select d;
foreach (FlaggedDate date in dates)
{
... etc.
}
Werden die Daten nicht tatsächlich heruntergeladen werden ("aufgelistet"), bis die foreach-Schleife ... richtig? In anderen Worten, die "var Termine" - Zeile definiert die Abfrage, aber die Abfrage wird nicht ausgeführt, bevor die foreach-Schleife.
Gegeben, dass (wenn meine Annahmen richtig sind), was ist der wirkliche Unterschied zwischen eager loading und lazy loading?? Es scheint, dass in beiden Fällen werden die Daten nicht angezeigt, bis die enumeration. Bin ich etwas fehlt?
(Meine konkrete Erfahrung mit code-first, POCO Entwicklung, die durch die Art und Weise ... aber die Fragen kann gilt mehr allgemein.)
InformationsquelleAutor der Frage Cynthia | 2010-09-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Beschreibung von (1) ist richtig, aber es ist ein Beispiel für Eager Loading eher als Lazy Loading.
Ihre Beschreibung von (2) falsch ist. (2) ist technisch kein laden, sondern wird Lazy Loading verwenden, wenn Sie versuchen, Zugriff auf nicht-Skalare Werte auf Ihre FlaggedDates.
In jedem Fall Sie sind richtig, dass keine Daten geladen werden, die aus Ihren Daten zu speichern, bis Sie versuchen, "etwas tun" mit der _flaggedDates. Was aber geschieht, ist in jedem Fall anders.
(1): Eager loading: sobald Sie beginnen, Ihre
for
Schleife, jedes der Objekte, die Sie angegeben haben, erhalten aus der Datenbank abgerufen und eingebaut in eine riesige in-memory-Daten-Struktur. Das wird ein sehr teurer Vorgang ist, zieht eine enorme Menge an Daten aus Ihrer Datenbank. Jedoch, es wird alles in einer Datenbank hin-und Rückfahrt, mit einer einzigen SQL-Abfrage immer ausgeführt.(2): Lazy loading: Wenn Ihr
for
Schleife beginnt, wird es nur geladen, die FlaggedDates Objekte. Wenn Sie jedoch den Zugriff auf zugehörige Objekte in diefor
Schleife, es wird nicht die Objekte in den Speicher geladen, noch. Der erste Versuch zum abrufen der scheduledSchools für einen bestimmten FlaggedDate resultieren entweder eine neue Datenbank-Roundtrips zum abrufen der Schulen, oder eine Ausnahme ausgelöst wird, weil sich Ihr Kontext bereits veräußert worden. Da wären Sie Zugriff auf die scheduledSchools-Sammlung in einefor
Schleife, Sie würden eine neue Datenbank round-trip-für jeden FlaggedDate, dass Sie zunächst geladen am Anfang derfor
Schleife.Antwort auf Kommentare
Deaktivieren von Lazy Loading ist nicht das gleiche wie die Aktivierung Eager Loading. In diesem Beispiel:
Den
schools
Variablen enthalten eine leere EntityCollection, weil ich nichtInclude
Sie in der ursprünglichen Abfrage (FlaggedDates.First () -), und ich deaktiviert, lazy loading, so dass Sie konnten nicht geladen werden nach der ersten Abfrage hingerichtet worden.Sind Sie richtig, dass die
where d.dateID == 2
würde bedeuten, dass nur die Objekte in Zusammenhang mit diesem spezifischen FlaggedDate Objekt gezogen werden. Allerdings, je nachdem, wie viele Objekte werden mit Bezug zum FlaggedDate, konnte Sie noch am Ende mit einer Menge von Daten, die über das Kabel. Dies ist aufgrund der Art, wie das Entity Framework baut seine SQL-Abfrage. SQL-Abfrage-Ergebnisse werden immer in einem tabellarischen format, das heißt, Sie müssen die gleiche Anzahl von Spalten für jede Zeile. Für jeden scheduledSchool Objekt, es muss mindestens eine Zeile in der Ergebnismenge, und da jede Zeile muss zumindest einige Wert für jede Spalte, die Sie am Ende mit jeder Skalare Wert auf Ihre FlaggedDate Objekt wiederholt. Also, wenn Sie 10 scheduledSchools und 10 interviews im Zusammenhang mit Ihrem FlaggedDate, werden Sie am Ende mit 20 Zeilen enthalten jeweils jeder Skalare Wert auf FlaggedDate. Die Hälfte der Reihen wird von null-Werten für alle ScheduledSchool Spalten, und die andere Hälfte wird von null-Werten für alle Interviews Spalten.Wo bekommt wirklich schlecht, aber, wenn Sie gehen "tief" in die Daten, die Sie einschließlich. Zum Beispiel, wenn jeder ScheduledSchool hatte
students
Eigenschaft, die Sie auch enthalten, dann plötzlich würden Sie eine Zeile für jeden Schüler in jedem ScheduledSchool, und auf jeder dieser Zeilen, jeder Skalare Wert für die Schüler ScheduledSchool einbezogen würden (obwohl nur die erste Zeile, die Werte am Ende immer verwendet), zusammen mit jeder Skalare Wert auf die original-FlaggedDate Objekt. Es kann oben schnell hinzufügen.Es ist schwer zu erklären in Schriftform, aber wenn man sich die eigentlichen Daten kommen aus einer query mit mehreren
Include
s, Sie werden sehen, dass es eine Menge doppelter Daten. Sie können LinqPad, um zu sehen, die SQL-Abfragen, die durch Ihre EF-code.InformationsquelleAutor der Antwort StriplingWarrior
Keinen Unterschied. Dies war nicht wahr, im EF 1.0 nicht unterstützt eager loading (zumindest nicht automatisch). In 1.0, man musste entweder ändern Sie die Eigenschaft automatisch zu laden, oder rufen Sie die Load () - Methode auf die Eigenschaft verweisen.
Eine Sache im Auge zu behalten ist, dass diejenigen, die Zählen können, gehen Sie in Rauch auf, wenn Sie die Abfrage über mehrere Objekte, wie z.B. so:
ObjectDate.MyObjectProperty werden nicht automatisch geladen.
InformationsquelleAutor der Antwort Chris B. Behrens