2011-10-12 13 views
49

se ho dichiarato relazione entità nel mio modello come virtuale, allora non v'è alcuna necessità di utilizzare l'istruzione Include nella mia query LINQ, giusto ?? -Entity Framework 4.1 Proprietà virtuale

Per esempio: Questa è la mia classe del modello :

public class Brand 
{ 
    public int BrandID { get; set; } 
    public string BrandName { get; set; } 
    public string BrandDesc { get; set; } 
    public string BrandUrl { get; set; } 

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

Ora, per la classe del modello di cui sopra, non ho bisogno di usare il var brandsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22);.

Invece, posso semplicemente usare il semplice var brandsAndProduct = pe.Brands.Where(brand => brand.BrandID == 22); e avrò automaticamente l'entità correlata disponibile quando si accede.

Sono corretto nella mia comprensione?

Inoltre, per favore dimmi in quali situazioni preferirei uno rispetto all'altro ??

risposta

158

Sei corretto ma la regola è più complessa per farlo funzionare davvero come previsto. Se si definisce la proprietà di navigazione virtual EF in fase di runtime crea una nuova classe (proxy dinamico) derivata dalla classe Brand e la utilizza invece. Questa nuova classe creata dinamicamente contiene la logica per caricare la proprietà di navigazione quando si accede per la prima volta. Questa funzione è chiamata caricamento lazy (o caricamento lazy trasparente migliore).

Quali regole devono essere incontrano per fare questo lavoro:

  • Tutte le proprietà di navigazione in categoria devono essere virtual
  • creazione di proxy dinamico non deve essere disabilitato (context.Configuration.ProxyCreationEnabled). Si è abilitata di default.
  • Il caricamento lento non deve essere disabilitato (context.Configuration.LazyLoadingEnabled). Si è abilitata di default.
  • L'entità deve essere allegata (impostazione predefinita se si carica l'entità dal database) al contesto e il contesto non deve essere eliminato = il caricamento lento funziona solo nell'ambito del contesto di vita utilizzato per caricarlo dal database (o in cui è stato collegato l'ente proxy)

L'opposto del caricamento lento è chiamato caricamento bisognoso ed è ciò che fa Include. Se si utilizza Include, la proprietà di navigazione viene caricata insieme all'entità principale.

L'utilizzo del caricamento lento e del caricamento impaziente dipende dalle esigenze dell'utente e anche dalle prestazioni. Include carica tutti i dati nella query di un singolo database ma può comportare huge data set quando si utilizza molto carico o carico di molte entità. Se sei sicuro di aver bisogno di Brand e di tutti gli Products per l'elaborazione, dovresti usare il caricamento bisognoso.

Il carico lento viene utilizzato a sua volta se non si è certi della proprietà di navigazione di cui si avrà bisogno. Ad esempio, se carichi 100 marchi, ma dovrai accedere solo ai prodotti di una marca, non è necessario caricare i prodotti per tutte le marche nella query iniziale. Lo svantaggio del caricamento lazy è una query separata (roundtrip del database) per ogni proprietà di navigazione => se carichi 100 marche senza includere e accederai alla proprietà Products in ogni istanza Brand il tuo codice genererà altre 100 query per popolare queste proprietà di navigazione = desideroso il caricamento usava solo la query singe ma il caricamento lazy utilizzava 101 query (si chiama N + 1 problema).

In scenari più complessi è possibile scoprire che nessuna di queste strategie funziona come necessario ed è possibile utilizzare una terza strategia chiamata caricamento esplicito o query separate per caricare marchi e prodotti per tutti i marchi necessari.

esplicita che il carico ha svantaggi simili come caricamento pigro ma è necessario innescare manualmente:

context.Entry(brand).Collection(b => b.Products).Load(); 

I principali vantaggi per il caricamento esplicito è la capacità di filtrare relazione. È possibile utilizzare Query() prima dello Load() e utilizzare qualsiasi filtraggio o persino il caricamento ansioso delle relazioni nidificate.

+3

Ritengo che questa risposta sia concisa e completa ... Grazie. Denominazione "Caricamento dati correlati" http://msdn.microsoft.com/en-us/magazine/hh205756.aspx – Lijo

+0

Grazie per la risposta. Ancora mi aiuta nel 2016. E ho ancora una domanda: C'è un modo per fare sempre carico ogni proprietà in una chiamata? Poiché ci sono alcune situazioni in cui i modelli hanno più proprietà di navigazione e devono essere caricati ogni volta. – anuith

Problemi correlati