26

Ich habe zwei ObjektklassenEntity Framework-Code Erst Lazy Loading-

public class User 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 

    // Navigation 
    public ICollection<Product> Products { get; set; } 
} 

public class Product 
{ 
    public Guid Id { get; set; } 

    // Navigation 
    public User User { get; set; } 
    public Guid User_Id { get; set; } 

    public string Name { get; set; } 
} 

Wenn ich einen Benutzer unter Verwendung von Datacontext laden, erhalte ich die Liste der Produkte null sein (das ist ok).

Wenn i „virtuelles“ Schlüsselwort Produkte Liste hinzuzufügen,

public virtual ICollection<Product> Products { get; set; } 

, wenn ich den Benutzer laden, bekomme ich die auch Produkte Liste.

Warum passiert das? Ich dachte, dass „virtuelle“ Schlüsselwort dies nicht das Laden der Einheiten, wenn Sie explizit verwendet wird (unter Verwendung eines „Include“ statement)

Ich glaube, ich habe alles falsch

+1

können Sie context.ContextOptions.LazyLoadingEnabled = false; Erzwingen des Kontexts, LazyLoading nicht zu verwenden –

+0

Mit dbContext wäre es context.Configuration.LazyLoadingEnabled = false; – VivekDev

Antwort

55

Das ist falsch

„virtuelle“ Schlüsselwort wird für nicht das Laden der Einheiten verwendet, sofern Sie explizit dies wird (eine „Include“ Anweisung) automatisch geladen

Lazy Loading-bedeutet, dass Unternehmen, wenn Sie greifen zuerst auf die Auflistungs- oder Navigationseigenschaft zu, und dies geschieht transparent, als ob sie immer mit dem übergeordneten Objekt geladen würden.

Die Verwendung von "include" wird bei Bedarf geladen, wenn Sie Eigenschaften angeben, die Sie abfragen möchten.

Existenz von virtual Schlüsselwort bezieht sich nur auf Lazy Loading. virtual Schlüsselwort ermöglicht Entity-Framework-Laufzeit Erstellen Sie dynamische Proxys für Ihre Entity-Klassen und ihre Eigenschaften, und dadurch unterstützt Lazy Loading. Ohne virtuelles Lazy Loading wird nicht unterstützt, und Sie erhalten null für die Collection-Eigenschaften.

Tatsache ist, dass Sie "include" in jedem Fall verwenden können, aber ohne Lazy Loading ist es die einzige Möglichkeit, auf Sammlung und Navigationseigenschaften zuzugreifen.

+0

_ "Lazy Loading bedeutet, dass Entitäten beim ersten Zugriff auf die Sammlung automatisch geladen werden" _ Dies bedeutet, dass die Produkte nicht geladen werden, wenn ich nie auf die user.Products-Eigenschaft zugreife. – Catalin

+0

@RaraituL: Richtig – abatishchev

+5

@RaraituL Ja, das stimmt.Wenn Sie debuggen, greifen Sie tatsächlich auf ** Eigenschaften zu, und sie werden geladen, wenn das verzögerte Laden unterstützt wird. Sie können also sql profiler oder ähnliche Tools zum Debuggen von tatsächlichen Abfragen verwenden, die an die Datenbank gesendet werden. – archil

4

Ich denke, Sie quiring für eine Eigenschaft das ist ein Thema für faule Last während in der Kontext ef sein:

using (var db = new Context()) 
{ 
    var user = db.Users.Where(...); 

    var products = user.Products; // being loaded right away 
} 

versuchen, es zu verlassen:

User user; 
using (var db = new Context()) 
{ 
    user = db.Users.Where(...); 

    // I guess you will need here: 
    // .Include(u => u.Products) 
} 
var products = user.Products; // what error will you get here? 
+0

ohne Verwendung von "virtual": Benutzer user = db.Users.First(); Im Debug-Modus ist user.Products null. Verwenden des Schlüsselworts "virtual": Benutzer user = db.Users.First(); Im debug-Modus ist user.Products eine Liste der Produkte – Catalin

+0

@RaraituL: Wie bereits erwähnt, müssen Sie das virtuelle Schlüsselwort im Code First-Ansatz verwenden, um das Lazy-Laden zu ermöglichen. Dann können Sie es ein- oder ausschalten. – abatishchev

+0

Aber der Kontext wurde vor "user.Products" "geschlossen", also wie das Lazy Laden funktioniert, wenn es Kontext gibt? – Nerf