2016-01-06 19 views
18

Ho letto questo tutorial e questo article ma non capisco esattamente l'uso di ciascun tipo di caricamento.Caricamento Eager, Lazy ed esplicito in EF6

spiego

ho questo POCO:

public partial class dpc_gestion 
{ 
    public dpc_gestion() 
    { 
     this.ass_reunion_participant = new HashSet<ass_reunion_participant>(); 
     this.dpc_participant = new HashSet<dpc_participant>(); 
     this.dpc_reunion = new HashSet<dpc_reunion>(); 
    } 

    public int dpc_id_pk { get; set; } 
    public Nullable<int> dpc_id_gdp_fk { get; set; } 
    public Nullable<int> dpc_id_theme { get; set; } 
    public int dpc_id_animateur_fk { get; set; } 
    public Nullable<System.DateTime> dpc_date_creation { get; set; } 
    public Nullable<System.DateTime> dpc_date_fin { get; set; } 
    public Nullable<System.DateTime> dpc_date_engag_anim { get; set; } 
    public Nullable<bool> dpc_flg_let_engag_anim { get; set; } 
    public Nullable<bool> dpc_flg_fsoins_anim { get; set; } 
    public virtual ICollection<ass_reunion_participant> ass_reunion_participant { get; set; } 
    public virtual theme_dpc theme_dpc { get; set; } 
    public virtual gdp_groupe_de_pair gdp_groupe_de_pair { get; set; } 
    public virtual ICollection<dpc_participant> dpc_participant { get; set; } 
    public virtual ICollection<dpc_reunion> dpc_reunion { get; set; } 
} 

ho capito questo:

  1. Per pigro carico: perché il carico è pigro, se io chiamo il dbset dpc_gestion non tutte le proprietà di navigazione non essere caricato. Questo tipo di caricamento è il migliore in termini di prestazioni e reattività. Si è abilitata di default e se mi piacerebbe riabilitarla devo impostare:

    context.Configuration.ProxyCreationEnabled = true;  
    context.Configuration.LazyLoadingEnabled = true; 
    
  2. Per l'eager loading Non è pigro: è caricato tutte le proprietà di navigazione quando carico dpc_gestion . Le proprietà di navigazione possono essere caricate utilizzando il metodo include. Per abilitare questo tipo di carico:

    context.Configuration.LazyLoadingEnabled = false; 
    
  3. per il caricamento esplicito È come l'eager loading, ma usiamo Load metodo invece di include.

Così mi piacerebbe sapere:

  1. Se questo piccolo curriculum è vero?
  2. Se è vero, qual è la differenza tra caricamento desideroso ed esplicito?
  3. Se utilizzo lazy caricando e chiamo per esempio dpc_gestion.dpc_participant, le proprietà di navigazione vengono caricate? O otterrò un'eccezione?
  4. Esiste un caso in cui il caricamento ansioso o il caricamento esplicito sono risultati migliori di un caricamento lento in termini di prestazioni e reattività?

Grazie

risposta

14

Se questo piccolo curriculum è vero?

Sì.

Se è vero, qual è la differenza tra carico desideroso ed esplicito?

Desideroso di carico è l'opposto di pigro carico ma esplicita carico è simile a caricamento pigro, eccetto che: si recuperano in modo esplicito i dati relativi a codice; non accade automaticamente quando accedi a una proprietà di navigazione. Caricare manualmente i dati correlati recuperando la voce di gestione stato oggetto per un'entità e chiamando il metodo Collection.Load per le raccolte o il metodo Reference.Load per le proprietà che contengono una singola entità.

Da techblog:

Caricare Eager:

carico Eager è il opposto caricamento lazy che è: Il processo di caricamento di uno specifico insieme di oggetti correlati insieme con gli oggetti che sono stati esplicitamente richiesti nella query.

esplicita di caricamento:

esplicita carico è definito come: quando gli oggetti vengono restituiti da una query, oggetti correlati non vengono caricati contemporaneamente. Per impostazione predefinita, sono caricati su fino a quando non vengono richiesti esplicitamente utilizzando il metodo Load su una proprietà di navigazione .

E:

se uso il caricamento pigro e io chiamo per esempio dpc_gestion.dpc_participant, fa le proprietà di navigazione carichi o io otterrà un'eccezione?

Non si ottiene alcuna eccezione e le proprietà di navigazione dovrebbero essere caricate.

C'è un caso in cui il carico di caricamento o caricamento esplicito era migliore di rispetto al carico lento in termini di prestazioni e reattività?

Desideroso di carico è in genere più efficace quando è necessario i dati correlati per tutte le righe recuperate della tabella primaria. E anche quando le relazioni non sono troppe, carico di lavoro sarà una buona pratica per ridurre ulteriormente le query sul server. Ma quando sai che non avrai bisogno di una proprietà istantanea, allora pigro carico forse una buona scelta. E anche il carico impaziente è una buona scelta in una situazione in cui il tuo contesto db viene eliminato e il caricamento lento non può più avvenire. Ad esempio si consideri il seguente:

public List<Auction> GetAuctions() 
{ 
    using (DataContext db = new DataContext()) 
    { 
     return db.Auctions.ToList(); 
    } 
} 

Dopo aver chiamato questo metodo, non è possibile caricare l'entità correlate pigramente perché il db è disposto e così il Eager Loading sarebbe una scelta migliore qui.

Una cosa da notare è: pigro carico produrrà diversi richiesta SQL durante Eager carico dati di carico con una sola richiesta. Eager caricamento è anche una buona scelta per risolvere il n + 1 seleziona il numero in ORM. Dai un'occhiata a questo post: What is the n+1 selects issue?

+1

@LamloumiAfif ... Un'altra cosa da notare è: il caricamento lento produrrà diverse richieste SQL mentre Eager carica i dati di carico con una richiesta. –

+0

Inoltre, l'impostazione 'LazyLoadingEnabled = false' non abilita il caricamento di eager. Disattiva il caricamento lento. È possibile caricare carico utilizzando 'Include' quando è abilitato il caricamento lazy – Colin

5

Domanda 1 e 2:

tua spiegazione di pigro carico e desiderosi di carico è corretta.
L'utilizzo del caricamento esplicito è leggermente diverso da quello descritto.

EntityFramework restituisce IQueryable oggetti, che contengono essenzialmente la query sul database. Ma questi non vengono eseguiti fino alla prima volta in cui vengono enumerati.
Load esegue la query in modo che i relativi risultati vengano archiviati localmente.
Chiamare Load equivale a chiamare ToList e buttare via quello List, senza avere il sovraccarico di creare il List.

Domanda 3:

Se si utilizza lazy loading, EntityFramework si occuperà di caricare la proprietà navigazione per voi, quindi non sarà possibile ottenere un'eccezione.
Ricordare che questo può richiedere un po 'di tempo e rendere l'applicazione non risponde.

Domanda 4:

In casi scollegati (ad esempio applicazione di rete) è non può uso lazy loading, perché questi oggetti vengono tradotti in DTOs e quindi non monitorate da EntityFramework.

Inoltre, se sai che stai andando ad utilizzare una proprietà navigazione, la sua buona pratica per caricarlo avidamente, quindi non c'è bisogno di aspettare fino a quando non vengono caricati dal database.
Ad esempio, si consente di memorizzare il risultato in un elenco e associarlo a un DataGrid WPF. Se DataGrid accede a una proprietà che non è ancora stata caricata, l'utente subisce un timeout notevole finché non viene visualizzata la proprietà. Inoltre l'applicazione non risponderà durante il tempo di caricamento (se non si carica in modo asincrono).

+2

Ricorda anche che per il caricamento lento il contesto deve essere attivo, altrimenti verrà generata un'eccezione. E direi che negli scenari disconnessi puoi * usare * il caricamento pigro finché stai costruendo il grafico degli oggetti che verrà serializzato, sebbene sia più comune caricare tutto ciò che ti serve esplicitamente, sia per 'Includi' o 'Carica' '. –

Problemi correlati