2015-07-12 31 views
37

Das verzögerte Laden in Entity Framework ist das Standardphänomen, das beim Laden und Zugreifen auf die zugehörigen Entitäten auftritt. Begieriges Laden bezieht sich jedoch auf die Praxis, alle diese Beziehungen zu erzwingen. Ich bin auf die Frage gestoßen, unter welcher Situation eifriges Laden nützlicher sein könnte als faules Laden. Da es offensichtlich ist, dass das faule Laden ressourcenschonender ist, und selbst wenn wir die ToList()-Methode verwenden, können wir immer noch das lazy loading-Verhalten ausnutzen. Ich dachte jedoch, dass das Lazy Loading die Anzahl der Anfragen an die tatsächliche Datenbank erhöht und vielleicht benutzen deshalb Entwickler manchmal die Methode Inlcude, um alle Beziehungen zwangsweise zu laden. Wenn Sie beispielsweise das Visual Studio-Auto-Scaffolding in MVC 5 verwenden, verwendet die Indexmethode, 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.Lazy Loading vs Eager Loading

Ich würde mich freuen, wenn mir jemand erklärt, unter welcher Situation eifriges Laden nützlicher wäre als faules Laden, und warum wir es überhaupt benutzen, während es etwas mehr Ressourcenfreundliches wie Lazy Loading gibt.

+6

Stellen Sie sich eine Situation vor, in der Ihr Db-Kontext entsorgt würde und das Lazy Loading nicht mehr stattfinden könnte. Dann ist eifriges Laden von Vorteil. – Transcendent

+1

Ich habe gesehen, dass viele Projekte aufgrund von Leistungsproblemen aufgrund des "N + 1 Select" -Problems scheitern, was beim lazy loading schneller auftreten wird, also sieh dir das an –

Antwort

37

Ich finde es gut ist, die Beziehungen zu kategorisieren wie diese

Wenn eifrig Laden

  1. In „einer Seite“ zu verwenden, von einer Eins-zu-viele Beziehungen, die Sie sicher, dass an allen Orten verwendet werden, mit Haupteinheit. wie Benutzereigenschaft eines Artikels. Kategorieeigenschaft eines Produkts.
  2. Allgemein Wenn Relationen nicht zu viel sind und eifrig geladen wird, ist es eine gute Methode, weitere Abfragen auf dem Server zu reduzieren.

Wenn verzögertes Laden

  1. Fast auf jeder "Sammlung Seite" one-to-many-Beziehungen verwenden. wie Artikel von Benutzer oder Produkte einer Kategorie
  2. Sie wissen genau, dass Sie nicht sofort eine Eigenschaft benötigen.

Hinweis: wie Transcendent sagte, es kann Entsorgung Problem mit Lazy Loading sein.

+5

Ich wollte nur versuchen, dasselbe zu beantworten. Verwenden Sie "Lazy Loading", wenn Sie wissen, dass Sie selten die entsprechenden Daten verwenden müssen. Aber wenn Sie wissen, dass Sie bestimmte verwandte Daten ziemlich oft wollen, verwenden Sie eifriges Laden. –

8

Lazy Laden wird mehrere SQL-Aufrufe erzeugen, während Eager Laden Daten mit einem "mehr schweren" Aufruf laden kann (mit Joins/Unterabfragen).

Zum Beispiel, wenn es einen hohen Ping zwischen Ihrem Web und Sql-Servern gibt, würden Sie mit Eager laden gehen anstatt verwandte Elemente 1-by-1 mit Lazy Loading zu laden.

9

Betrachten Sie die unten 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(); 
    } 
} 

Jetzt, nach dieser Methode aufgerufen wird, können Sie die Employer Einheit nicht mehr faul Last. Warum? weil das Objekt db entsorgt wird. Sie müssen also Person.Include(x=> x.employer) tun, um das Laden zu erzwingen.

+2

Ja, das ist ein Beispiel, wenn Lazy Loading nicht hilft. Eine andere Sache ist, dass das Erstellen von DbContext immer dann, wenn Sie einige Daten benötigen, schlecht ist. Wenn Sie einen IoC-Container verwenden, wird Ihr DbContext zusammen mit Request (im Falle von Web-Apps) ausgeführt. –

+0

@MiroslavHolec: Brilliant, das mache ich eigentlich mit Ninject. Was Sie gerade erwähnt haben, ist in der Tat sehr, sehr nett. – Transcendent

0
// 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(); 
} 
+0

Während dieses Code-Snippet die Frage lösen kann, [hilft eine Erklärung] (http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) wirklich, um die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in der Zukunft beantworten, und diese Leute könnten die Gründe für Ihren Codevorschlag nicht kennen. – Arefly

+0

Diese Antwort behandelt überhaupt keine OP-Frage. OP fragt nicht, wie man 'Lazy loading' machen soll, er fragt nach" wann man 'Lazy loading' und wann' Eager Loading' verwendet. – Mischa

5

Eager Loading: Eager Loading hilft Ihnen sofort alle benötigten Einheiten zu laden. d.h.verwandte Objekte (untergeordnete Objekte) werden automatisch mit dem übergeordneten Objekt geladen.

Wann verwendet:

  1. Verwenden Eager Laden, wenn die Beziehungen nicht zu viel sind. Daher ist Eager Loading eine gute Methode, um weitere Abfragen auf dem Server zu reduzieren.
  2. Verwenden Sie Eager Loading, wenn Sie sicher sind, dass Sie verwandte Entitäten mit der Haupteinheit überall verwenden werden.

Lazy Loading-: Bei verzögertes Laden, verwandte Objekte (Child-Objekte) werden nicht automatisch mit seinem übergeordneten Objekt geladen, bis sie angefordert werden. LINQ unterstützt standardmäßig Lazy Loading.

Wann verwendet:

  1. Verwenden Lazy Loading-wenn Sie eine Eins-zu-viele Sammlungen verwenden.
  2. Verwenden Sie Lazy Loading, wenn Sie sicher sind, dass Sie verwandte Objekte nicht sofort verwenden.

HINWEIS: Entity Framework unterstützt drei Arten bezogene Daten zu laden - eifrig Laden, verzögertes Laden und expliziten Laden.