Lazy Loading vs Eager Loading

79

Das verzögerte Laden in Entity Framework ist das Standardphänomen beim Laden und Zugreifen auf die zugehörigen Entitäten. Eifriges Laden bezieht sich jedoch auf die Praxis des Belastens all dieser Beziehungen. Ich bin auf die Frage gestoßen, in welcher Situation eifriges Laden vorteilhafter sein könnte als faules Laden. Fragen Sie dies, da es offensichtlich ist, dass verzögertes Laden ressourcenschonender ist, und selbst wenn wir die ToList()Methode verwenden, können wir das verzögerte Ladeverhalten dennoch nutzen. Ich dachte jedoch, dass ein verzögertes Laden die Anzahl der Anforderungen an die eigentliche Datenbank erhöht, und vielleicht verwenden Entwickler deshalb manchmal dieInlcudeMethode zum erzwungenen Laden aller Beziehungen. Wenn Sie beispielsweise das automatische Visual Studio-Gerüst in MVC 5 verwenden, verwendet die Index-Methode, die automatisch im Controller erstellt wird, immer Eager Loading, und ich hatte immer die Frage, warum Microsoft in diesem Fall standardmäßig Eager Loading verwendet.

Ich würde mich freuen, wenn mir jemand erklärt, in welcher Situation eifriges Laden vorteilhafter ist als faules Laden, und warum wir es überhaupt verwenden, während es etwas ressourcenschonenderes gibt als Lazy Loading.

Arnold Zahrneinder
quelle
8
Stellen Sie sich eine Situation vor, in der Ihr Datenbankkontext verfügbar wäre und kein verzögertes Laden mehr möglich wäre. Dann ist eifriges Laden von Vorteil.
Transzendent
2
Ich habe gesehen, dass viele Projekte aufgrund von Leistungsproblemen aufgrund des Problems "N + 1 Select" fehlschlagen, das beim verzögerten Laden schneller auftritt. Schauen Sie also unbedingt nach
David DV,

Antworten:

79

Ich denke, es ist gut, solche Beziehungen zu kategorisieren

Wann sollte man eifriges Laden verwenden?

  1. In "einer Seite" von Eins-zu-Viele-Beziehungen, die Sie sicher überall mit der Hauptentität verwenden. wie Benutzereigenschaft eines Artikels. Kategorieeigenschaft eines Produkts.
  2. Im Allgemeinen, wenn die Beziehungen nicht zu groß sind und das eifrige Laden eine gute Vorgehensweise ist, um weitere Abfragen auf dem Server zu reduzieren.

Wann ist Lazy Loading zu verwenden?

  1. Fast auf jeder "Sammlungsseite" von Eins-zu-Viele-Beziehungen. wie Artikel des Benutzers oder Produkte einer Kategorie
  2. Sie wissen genau, dass Sie eine Immobilie nicht sofort benötigen.

Hinweis: Wie Transcendent sagte, liegt möglicherweise ein Entsorgungsproblem beim verzögerten Laden vor.

farid bekran
quelle
5
Ich habe nur versucht, das Gleiche zu beantworten. Verwenden Sie das verzögerte Laden, wenn Sie wissen, dass Sie die zugehörigen Daten selten verwenden müssen. Wenn Sie jedoch wissen, dass Sie bestimmte verwandte Daten häufig benötigen, sollten Sie eifrig laden.
Ghasan
Kann ich beide zusammen verwenden? Wenn zum Beispiel eine Entität fast mit einer anderen verwandt ist, kann ich sie durch eifriges Laden einschließen, und andere verwandte Entitäten werden durch verzögertes Laden aufgenommen.
Ahmad Alaa
27

Eifriges Laden: Eifriges Laden hilft Ihnen, alle benötigten Entitäten gleichzeitig zu laden. dh verwandte Objekte (untergeordnete Objekte) werden automatisch mit ihrem übergeordneten Objekt geladen.

Wann zu verwenden:

  1. Verwenden Sie Eager Loading, wenn die Beziehungen nicht zu groß sind. Daher ist das eifrige Laden eine gute Vorgehensweise, um weitere Abfragen auf dem Server zu reduzieren.
  2. Verwenden Sie Eager Loading, wenn Sie sicher sind, dass Sie überall verwandte Entitäten mit der Hauptentität verwenden.

Lazy Loading: Beim Lazy Loading werden verwandte Objekte (untergeordnete Objekte) erst dann automatisch mit dem übergeordneten Objekt geladen, wenn sie angefordert werden. Standardmäßig unterstützt LINQ das verzögerte Laden.

Wann zu verwenden:

  1. Verwenden Sie Lazy Loading, wenn Sie Eins-zu-Viele-Sammlungen verwenden.
  2. Verwenden Sie Lazy Loading, wenn Sie sicher sind, dass Sie verwandte Entitäten nicht sofort verwenden.

HINWEIS: Entity Framework unterstützt drei Möglichkeiten zum Laden verwandter Daten: Eifriges Laden, verzögertes Laden und explizites Laden.

Dunkle Materie
quelle
Ich bin wirklich verwirrt über eifriges und faules Laden. Könntest du mich bitte verstehen lassen? Mit Bezug auf Google könnte ich dieses Ding über faules Laden machen. "Sie sollten das virtuelle Schlüsselwort verwenden, wenn Sie Daten mit verzögertem Laden laden möchten. Das verzögerte Laden ist der Prozess, bei dem eine Entität oder eine Sammlung von Entitäten beim ersten Zugriff automatisch aus der Datenbank geladen wird. 7. Januar 2016" ist das das gleiche, was Sie über faules Laden gesagt haben.
Rykamol
@rykamol Versuchen Sie es als Designmuster zu verstehen. Weitere Informationen finden Sie hier: Eifriges Laden - entityframeworktutorial.net/… , Lazy Loading - entityframeworktutorial.net/… , Explizites Laden - entityframeworktutorial.net/EntityFramework4.3/…
Dunkle Materie
20

Beim verzögerten Laden werden mehrere SQL-Aufrufe ausgeführt, während beim eifrigen Laden möglicherweise Daten mit einem "schwereren" Aufruf (mit Joins / Unterabfragen) geladen werden.

Wenn beispielsweise zwischen Ihrem Web und den SQL-Servern ein hoher Ping-Wert besteht, wird das Eager-Laden fortgesetzt, anstatt die zugehörigen Elemente 1: 1 mit dem verzögerten Laden zu laden.

Serhiyb
quelle
Kann ich beide zusammen verwenden? Wenn zum Beispiel eine Entität fast mit einer anderen verwandt ist, kann ich sie durch eifriges Laden einschließen, und andere verwandte Entitäten werden durch verzögertes Laden aufgenommen.
Ahmad Alaa
12

Betrachten Sie die folgende Situation

public class Person{
    public String Name{get; set;}
    public String Email {get; set;}
    public virtual Employer employer {get; set;}
}

public List<EF.Person> GetPerson(){
    using(EF.DbEntities db = new EF.DbEntities()){
       return db.Person.ToList();
    }
}

Nachdem diese Methode aufgerufen wurde, können Sie die EmployerEntität nicht mehr verzögert laden . Warum? weil das dbObjekt entsorgt ist. Sie müssen Person.Include(x=> x.employer)also das Laden erzwingen.

Transzendent
quelle
3
Ja, das ist ein Beispiel, wenn Lazy Loading nicht hilft. Eine andere Sache ist, dass das Erstellen von DbContext jedes Mal, wenn Sie Daten benötigen, ein schlechter Weg ist. Wenn Sie einen IoC-Container haben, wird Ihr DbContext zusammen mit Request (im Fall von Web-Apps) verwendet.
Miroslav Holec
@MiroslavHolec: Genial, das mache ich eigentlich mit Ninject. Was Sie gerade erwähnt haben, ist in der Tat sehr, sehr schön.
Transzendent
8

Eifriges Laden Wenn Sie sicher sind, dass mehrere Entitäten gleichzeitig abgerufen werden sollen, z. B. Benutzer und Benutzerdetails auf derselben Seite anzeigen müssen, sollten Sie mit dem eifrigen Laden fortfahren. Eifriges Laden führt zu einem einzigen Treffer in der Datenbank und lädt die zugehörigen Entitäten.

Lazy Loading Wenn Sie Benutzer nur auf der Seite anzeigen müssen und durch Klicken auf Benutzer Benutzerdetails anzeigen müssen, müssen Sie mit Lazy Loading fortfahren. Beim verzögerten Laden werden mehrere Treffer erzielt, um die zugehörigen Entitäten zu laden, wenn Sie verwandte Entitäten binden / iterieren.

Sheriff
quelle
1

Lazy Loading - ist gut, wenn mit Paginierung wie auf der Seite geladen wird. Es wird eine Liste mit Benutzern angezeigt, die 10 Benutzer enthält. Wenn der Benutzer die Seite nach unten scrollt, bringt ein API-Aufruf die nächsten 10 Benutzer. Es ist gut, wenn Sie keine vollständigen Daten bei laden möchten einmal, da es mehr Zeit in Anspruch nehmen und eine schlechte Benutzererfahrung bieten würde.

Eifriges Laden - ist gut, wie andere Leute vorgeschlagen haben, wenn nicht viele Beziehungen bestehen und ganze Daten auf einmal in einem einzigen Aufruf der Datenbank abgerufen werden

Iqra Abdul Rauf
quelle
-1

Es ist besser, eifriges Laden zu verwenden, wenn dies möglich ist, da dies die Leistung Ihrer Anwendung optimiert.

Ex-:

Eager loading

var customers= _context.customers.Include(c=> c.membershipType).Tolist();

lazy loading

Im Modell muss der Kunde definieren

Public virtual string membershipType {get; set;}

Wenn Sie also das verzögerte Laden abfragen, wird das Laden aller Referenzobjekte viel langsamer, aber das eifrige Laden fragt ab und wählt nur das Objekt aus, das relevant ist.

Nuwan Dhanushka
quelle
Verwenden Sie Leistungsdiagnosetools wie Glimpse und überprüfen Sie, wie beide funktionieren, während beim verzögerten Laden mehrere Verbindungen und Abfragen nur eine haben. Ich habe diese praktisch überprüft, bitte erwähnen Sie, warum Sie das falsch sagen.
Nuwan Dhanushka
#FakeCaleb hat seinen Kommentar entfernt
Nuwan Dhanushka
Ein Mod hat meinen Kommentar entfernt. Ich habe keinen Sinn darin gesehen, dieses Gespräch fortzusetzen, da Sie meinen Kommentar sowieso aus Ihrer Antwort missverstanden haben
FakeCaleb
Sie haben den genauen Punkt nicht erwähnt und gesagt, dass mein Kommentar völlig irreführend ist. Wenn Sie erwähnen, welche Punkte falsch sind, kann ich auch lernen.
Nuwan Dhanushka
Ich denke nur, dass Sie aufgrund der Formulierung darauf hinweisen, dass eifriges Laden aufgrund der Leistung besser ist als faules Laden. Ich kann mir Szenarien vorstellen, in denen dies nicht stimmt.
FakeCaleb
-2
// Using LINQ and just referencing p.Employer will lazy load
// I am not at a computer but I know I have lazy loaded in one
// query with a single query call like below.
List<Person> persons = new List<Person>();
using(MyDbContext dbContext = new MyDbContext())
{
    persons = (
        from p in dbcontext.Persons
        select new Person{
            Name = p.Name,
            Email = p.Email,
            Employer = p.Employer
        }).ToList();
}
Matt Empringham
quelle
1
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich dabei, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Er Yifei
1
Diese Antwort behandelt die Frage des OP überhaupt nicht. OP fragt nicht, wie es geht Lazy loading, er fragt nach "wann Lazy loadingund wann Eager Loading"
Mischa