26

che sto avendo due classi di oggettiEntity Framework Codice primo caricamento pigro

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; } 
} 

quando carico un utente che utilizza DataContext, ho l'elenco dei prodotti in nulla (questo è ok).

se aggiungo parola chiave "virtuale" alla lista prodotti,

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

quando carico l'utente, ho la lista dei prodotti pure.

Perché sta succedendo? Ho pensato che parola chiave "virtuale" viene utilizzato per non caricare le entità a meno che non esplicitamente questo (utilizzando un "include" economico)

Penso che ho sbagliato tutto

+1

è possibile utilizzare context.ContextOptions.LazyLoadingEnabled = false; per forzare il contesto a non utilizzare LazyLoading –

+0

Con dbContext sarebbe context.Configuration.LazyLoadingEnabled = false; – VivekDev

risposta

55

Questo è sbagliato

parola chiave "virtuale" viene utilizzato per non caricare le entità a meno che non esplicito questo (utilizzando un "include" dichiarazione)

caricamento pigro significa che le entità saranno caricati automaticamente quando per prima cosa accedi alla raccolta o alla proprietà di navigazione e ciò avverrà in modo trasparente, come se fossero sempre caricati con oggetto padre.

L'utilizzo di "include" viene caricato su richiesta, quando si specificano le proprietà che si desidera interrogare.

L'esistenza della parola chiave virtual è correlata solo al caricamento lazy. La parola chiave virtual consente al runtime di framework di entità di creare proxy dinamici per le classi di entità e le relative proprietà e da tale supporto per il caricamento lento. Senza il caricamento virtuale, il caricamento non sarà supportato e si ottengono valori null sulle proprietà della raccolta.

Il fatto è che è possibile utilizzare "include" in ogni caso, ma senza caricare pigro è l'unico modo per accedere alle proprietà di raccolta e navigazione.

+0

_ "Caricamento lento indica che le entità verranno caricate automaticamente quando si accede per la prima volta alla raccolta" _ Ciò significa che se non accedo mai alla proprietà user.Products, i prodotti non verranno caricati, giusto? – Catalin

+0

@RaraituL: Right – abatishchev

+5

@RaraituL sì, è giusto.Quando esegui il debug, in realtà ** accedi a ** proprietà e vengono caricati se è supportato il caricamento lento. Quindi è possibile utilizzare sql profiler o strumenti simili per eseguire il debug di query effettive inviate al database. – archil

4

immagino che stai Quiring per una proprietà che è un oggetto per carico artificiale pur essendo in contesto ef:

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

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

Prova a lasciare:

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

senza utilizzare "virtuale": Utente utente = db.Users.First(); in modalità di debug, user.Products è nullo. utilizzando la parola chiave "virtuale": Utente utente = db.Users.First(); in modalità debug, user.Products è un elenco di prodotti – Catalin

+0

@RaraituL: come già menzionato in precedenza, è necessario utilizzare la parola chiave virtuale nell'approccio Code First per rendere possibile il caricamento lazy. Quindi puoi accenderlo o spegnerlo. – abatishchev

+0

Ma il contesto era "chiuso" prima di "user.Products", quindi come funziona il caricamento Lazy se c'è un contesto? – Nerf