Devo abilitare o disabilitare i proxy dinamici con Entity Framework 4.1 e MVC3?

Qualcuno potrebbe offrire qualche consiglio o indicare alcuni blog / articoli che potrebbero aiutare a prendere questa decisione? I delegati mi sembrano molto estranei e sono riluttante a usarli. Mi piace la capacità di controllare il caricamento lento utilizzando le proprietà virtuali nel mio modello, ma questo è praticamente tutti i vantaggi che posso vedere. La mia applicazione è una semplice applicazione web MVC e non ho bisogno di colbind nessun hook nel contesto per quando le quadro subiscono uno stato modificato.

Ad ogni modo, ecco la mia lista molto limitata di pro e contro in questo momento, fammi sapere se sono fuori base con tutto questo.

Professionisti

  • Su “Salva” o “Aggiorna”, ottengo senza problemi con “Applica” Cambiamenti ”
  • La configurazione a caricamento lento è molto semplice.

Contro

  • Non ho mai usato i proxy prima per le mie quadro, questo è un cambiamento nell’approccio che sembra solo scomodo per me stesso e gli altri membri del team.
  • Imbarazzo per il debug.
  • Richiede codice aggiuntivo se voglio serializzare / de-serializzare
  • Su ‘Salva’ o ‘Aggiorna’, il proxy deve essere lo stesso object che è stato recuperato dal contesto.

Se parli di proxy dinamici in EF ci sono due diversi tipi di distinzione:

  • Proxy per il caricamento lento
  • Proxy per il rilevamento delle modifiche

Di solito un proxy di tracciamento delle modifiche può anche fungere da proxy per il caricamento lento. Il contrario non è vero. Questo perché i requisiti per i proxy di rilevamento delle modifiche sono più elevati, in particolare tutte le proprietà, anche quelle scalari, devono essere virtual . Per il caricamento lento è sufficiente che le proprietà di navigazione siano virtual .

Il fatto che un proxy di rilevamento modifiche consenta sempre di sfruttare il carico lento è la ragione principale per cui DbContext ha questo flag di configurazione:

 DbContext.Configuration.LazyLoadingEnabled 

Questo flag è true per impostazione predefinita. Impostandolo su false disabilita il caricamento lazy anche se vengono creati dei proxy. Ciò è particolarmente importante se si sta lavorando con i proxy di rilevamento modifiche ma non si desidera utilizzare anche quei proxy per il caricamento lazy.

L’opzione …

 DbContext.Configuration.ProxyCreationEnabled 

… disabilita completamente la creazione del proxy, anche per il rilevamento delle modifiche e il caricamento lento.

Entrambi i flag hanno un significato solo se le classi di entity framework soddisfano i requisiti per la creazione di un rilevamento modifiche o di proxy di caricamento lazy.

Ora conosci lo scopo dei proxy dinamici di caricamento pigro. Quindi, perché dovremmo usare i proxy dinamici per il rilevamento delle modifiche?

In realtà l’unica ragione per cui sono consapevole è la performance . Ma questa è una ragione molto forte. Confrontando il rilevamento delle modifiche basato su snapshot con il rilevamento delle modifiche basato su proxy, la differenza di prestazioni è enorme: dalle mie misurazioni un fattore da 50 a 100 è realistico (preso da un metodo che richiede circa un’ora per 10000 entit con rilevamento delle modifiche basato su snapshot e da 30 a 60 secondi dopo aver reso tutte le proprietà virtuali per abilitare i proxy di rilevamento delle modifiche). Questo sta diventando un fattore importante se si dispone di un’applicazione che elabora e modifica molte entity framework (diciamo più di 1000). In un’applicazione web in cui è ansible eseguire solo operazioni di creazione / modifica / eliminazione su singole quadro in una richiesta Web, questa differenza non ha importanza.

In quasi tutte le situazioni è ansible sfruttare il carico impaziente o esplicativo per raggiungere lo stesso objective se non si desidera lavorare con i proxy di caricamento lazy. Le prestazioni per il caricamento lazy basato su proxy o il caricamento di explicite basato su proxy non sono le stesse perché fondamentalmente la stessa query avviene quando vengono caricate le proprietà di navigazione – nel primo caso il proxy fa la query, nel secondo caso il codice scritto a mano. Quindi, puoi vivere senza proxy di caricamento pigro senza perdere molto.

Ma se si desidera che le prestazioni ragionevoli EntityObject molte, molte entity framework non c’è alternativa al cambiamento dei proxy di tracciamento – a parte l’uso di entity framework derivate EntityObject in EF 4.0 (non un’opzione in EF 4.1 perché è proibito quando si utilizza DbContext ) o non si utilizza Entity Framework affatto.

Modifica (maggio 2012)

Nel frattempo ho appreso che ci sono situazioni in cui i proxy di rilevamento modifiche non sono più veloci o peggiori nelle prestazioni rispetto al tracciamento basato su snapshot.

A causa di queste complicazioni quando si utilizzano i proxy di rilevamento delle modifiche, il modo preferito è utilizzare il rilevamento delle modifiche basato su snapshot per impostazione predefinita e utilizzare i proxy con attenzione (dopo aver eseguito alcuni test) solo nelle situazioni in cui è richiesta una prestazione elevata e dove si dimostrano più veloci di quelli basati su snapshot cambiare tracciamento.

Per chiunque utilizzi Entity Framework 5, assicurati di consultare l’articolo Considerazioni sulle prestazioni . Sections 5 NoTracking Queries e 8 Loading Related Entities offre le informazioni necessarie per prendere una decisione informata. Saluti.

Vorrei suggerire di NON usare i proxy. La creazione del proxy dinamico interrompe o crea complicazioni per i componenti che dipendono dal controllo del tipo di runtime.

Automapper, ad esempio, genererà un errore di tipo mancata corrispondenza / tipo inaspettato durante il runtime in quanto le entity framework avranno i tipi di proxy generati dynamicmente durante il runtime e non i tipi passati durante la configurazione della creazione automatica.

Sebbene i proxy dinamici abbiano alcune caratteristiche interessanti, in realtà possono creare molti bug strani e oscuri.

Ad esempio, una variabile privata mantenuta di un’entity framework in una delle mie classi (stava implementando un processo batch) e io stavo eseguendo il ciclo di alcuni milioni di record, elaborandoli e inserendoli in batch, ricreando il contesto dei dati ogni n-record in pulisci la memoria. Sebbene non abbia MAI usato la variabile privata, EF la stava collegando ai miei nuovi oggetti (c’era un riferimento attraverso una proprietà di navigazione) anche se stavo solo impostando l’Id di riferimento.

Ciò ha causato la permanenza di tutti gli oggetti nella memoria per tutto il tempo in cui il processo era in esecuzione. Ho dovuto utilizzare AsNoTracking e disabilitare i proxy affinché il processo funzionasse come previsto e la memoria e le prestazioni tornassero ai livelli normali. Tieni presente che i proxy fanno riferimento anche al contesto che li ha creati e questo può tenere in memoria enormi grafici di quadro, è quasi imansible eseguirne il debug

Quindi, credo che dovresti disabilitare globalmente i proxy e abilitarli in piccole parti di codice contenute. È molto pericoloso e imansible eseguire il debug di questi problemi, soprattutto quando si hanno codifiche di grandi squadre.

Il rilevamento delle modifiche è piacevole, potrebbe giustificare l’utilizzo in alcuni punti. Il caricamento lento può rappresentare un grosso problema in termini di prestazioni e serializzazione, a meno che tu non sappia cosa stai facendo. Preferisco caricamenti desiderosi o espliciti in ogni momento.

Usa Automapper 4.2.1. La nuova versione non ha DynamicMap

 var parents = parentsRepo.GetAll().ToList(); Mapper.CreateMap(); var parentsDto = Mapper.DynamicMap>(parents);