Ich untersuche die Grundlagen der Datenschicht für ein neues webbasiertes Berichtssystem und habe viel Zeit mit der Auswertung von ORMs in den letzten Tagen verbracht. Das heißt, ich habe mich noch nie mit "Lazy Loading" beschäftigt und bin verwirrt darüber, warum dies die Standardeinstellung für LINQ-Abfragen im Entity Framework ist. Es scheint, als würde es viel Netzwerkverkehr erzeugen und die Datenbank unnötigerweise mit zusätzlichen Abfragen versorgen, die sonst mit Joins aufgelöst werden könnten.
Kann jemand ein Szenario beschreiben, in dem eine verzögerte Ladung von Vorteil wäre?
Einige Meta:
Das neue System wird gegen eine Datenbank mit Hunderten von Tabellen und vielen Terabyte an Daten in einer Produktionsumgebung mit über 3.000 gleichzeitigen Benutzern auf dem System 24 Stunden am Tag arbeiten. Sie werden fortlaufend große Datensätze abrufen. Ist es möglich, dass ein ORM für unsere Bedürfnisse nicht die richtige Lösung ist, zumal die App webbasiert ist?
Wenn wir über Lazy Loading sprechen, sprechen wir über Navigationseigenschaften (wie wir Fremdschlüsseln folgen). Was das Lazy Loading für uns tun wird, besteht darin, die Entity von einer entfernten Tabelle aus zu füllen, wenn wir versuchen, auf diese Entität zuzugreifen. Zum Beispiel, wenn wir ein solches Modell haben
%Vor%Und ruf folgendes an
%Vor% Wir erhalten 2 Datenbankaufrufe, einen für WhateverContext.TestEntities.First()
und einen für das Laden der entfernten Entität.
Ich bin ein Web-Typ (und genauer gesagt ein MVC-Typ) und für Web-Sachen glaube ich nicht, dass es jemals einen guten Grund gibt, dies zu tun. Ein Datenbank-Aufruf wird immer schneller als zwei sein wenn wir die gleichen Daten benötigen.
Die Situation, in der ich denke, dass Lazy Loading tatsächlich eine Überlegung wert ist, ist, wenn Sie nicht wissen, wann Sie Ihre erste Anfrage machen, wenn Sie die zweite Entität überhaupt brauchen. Meiner Meinung nach ist dies viel relevanter für Windows-Anwendungen, wo wir einen Benutzer haben, der Aktionen in Echtzeit ausführt (anstatt staatenloser MVC, wo Benutzer ganze Seiten gleichzeitig anfordern). Zum Beispiel glaube ich, dass Lazy Loading glänzt, wenn wir eine Liste von Daten mit einem Details-Link haben, dann laden wir die Details nicht, bis der Benutzer entscheidet, dass sie sie sehen wollen.
Ich glaube nicht, dass sich das auf Paging, Sortierung und Filterung erstreckt. IMO sollte es eine speziell gestaltete Datenbankabfrage pro angezeigter Seite geben, die genau den Datensatz zurückgibt, der zum Anzeigen dieser Seite erforderlich ist.
In Bezug auf Ihre Frage zur Leistung habe ich das Gefühl, dass EF (oder ein anderes ORM) hier wahrscheinlich Ihren Anforderungen entsprechen kann, aber Sie möchten aufgrund der Art und Weise, wie EF Einheiten verfolgt, vorsichtig sein, wie große Datasets abgerufen werden. Schau dir mein Spickzettel zur EF-Optimierung an und lies es dir durch auf DetectChanges und AsNoTracking wenn Sie EF mit großen Abfragen verwenden möchten.
Die meisten ORMs geben Ihnen die Möglichkeit, wenn Sie Ihre Objektauswahl erstellen, zu sagen: "Sei nicht faul, mach weiter und mach mit". Wenn du also aus Effizienzgründen besorgt bist, don nicht sein. Sie können es (normalerweise) zum Laufen bringen.
Es gibt 2 Fälle, in denen ich weiß, wo das Lazy Loading hilft:
Verkettungsbefehle Was ist, wenn Sie eine grundlegende Auswahl erstellen möchten, die Sie dann aber über eine Sortierfunktion und eine Filterfunktion ausführen möchten, die auf Benutzereingaben basiert? Sie können das ORM-Objekt einfach übergeben und ihm die Sortier- und Filterfunktion zuordnen. Anstatt es jedes Mal auszuwerten, wertet es nur aus, wenn es tatsächlich verwendet wird.
Vermeiden Sie große, tiefe, hoch-relationale Anfragen Was ist, wenn Sie nur die IDs einiger verwandter Felder benötigen? Wenn es langsam geladen wird, müssen Sie sich nicht darum sorgen, dass es sich einer ganzen Reihe von Daten und Tabellen anschließt, die Sie nicht benötigen, wodurch die Abfrage möglicherweise verlangsamt und die Bandbreite überlastet wird. Natürlich, wenn Sie alles andere wollen, dann müssen Sie explizit sein, oder Sie können auf ein Problem stoßen, wo es eine Abfrage für jeden Detail-Datensatz führt. Wie ich eingangs erwähnt habe, ist das in jedem ORM, das es wert ist, zu verwenden, leicht zu überwinden.
Ein einfacher Fall ist eine Ergebnismenge von N Datensätzen, die Sie nicht gleichzeitig zum Client bringen wollen. Der Vorteil ist, dass Sie in der Lage sind, nur das zu laden, was für die Kundenanforderungen benötigt wird, wie Sortieren, Filtern, etc ... Ein Beispiel wäre eine Paging-Ansicht, in der Datensätze durchsucht und entsprechend sortiert werden können, also der Client benötigt nur N Menge zu einer bestimmten Zeit.
Wenn Sie die LINQ-Abfrage ausführen, übersetzt sie das in SQL-Befehle auf der Serverseite, um nur das zu liefern, was im gegebenen Kontext benötigt wird. Es läuft darauf hinaus, die Arbeit an die Datenbank auszulagern und zu minimieren, was Sie an den Client zurücksenden müssen.
Einige werden argumentieren, dass ORM-basiertes Lazy Loading falsch ist, aber relativ schnell in die Semantik übergeht und mehr über den Ansatz zum Design im Vergleich zu richtig und falsch sein sollte .
Tags und Links entity-framework orm nhibernate