21

Ho un progetto su MVC. Abbiamo scelto EF per le nostre transazioni DB. Abbiamo creato alcuni gestori per il livello BLL. Ho trovato un sacco di esempi, in cui si utilizza "using" l'istruzione, vale a direUso di EF (entità framework) dell'istruzione "using"

public Item GetItem(long itemId) 
    { 
     using (var db = new MyEntities()) 
     { 
      return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault(); 
     } 
    } 

Qui creiamo una nuova istanza di DbContext MyEntities(). Utilizziamo "using" per "ensure the correct use of IDisposable objects."

È solo un metodo nel mio manager. Ma ne ho più di dieci. Ogni volta che chiamo un metodo dal gestore, userò lo statino "using" e lo creerà un altro DBcontext nella memoria. Quando Garbage Collector (GC) li smaltirà? Chissà?

Ma esiste un'altra alternativa all'utilizzo dei metodi di gestione. Creiamo una variabile globale:

private readonly MyEntities db = new MyEntities(); 

e usiamo DbContext in ogni metodo senza "using" dichiarazione. E il metodo è simile al seguente:

public Item GetItem(long itemId) 
{ 
    return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault(); 
} 

Domande:

  1. Qual è il modo corretto di usare variabili DbContext?
  2. E se non usassimo la frase "usage" (perché influisce sulle prestazioni) - GC farà tutto per quello?

Sono un "debuttante" in uso EF e ancora non ho trovato la risposta univoca per questa domanda.

+0

Dipende quanto lontano si vuole prendere. Idealmente non lo istanziate affatto nel controller, ma invece ** Inietti ** (IoC/DI) in questo modo qualunque cosa stia chiamando controller (Factory) può determinare la durata del Context. – Belogix

+0

Perché influisce sulle prestazioni? L'hai misurato e hai concluso che stai perdendo le prestazioni? E il GC non lo sta smaltendo, lo stai smaltendo da solo poiché stai usando le istruzioni using. – Maarten

risposta

11

Penso che troverete molti suggerendo questo stile di modello. Non solo a me o Henk DBContext handling

  • Sì, preferibilmente utilizzando dichiarazioni a DbContext sottotipi
  • Ancora meglio Unità di modelli di lavoro che sono gestiti con utilizzo, che hanno un contesto e smaltiscono contesto Just 1 of many UoW examples, this one from Tom Dykstra
  • L'Unità Di Work Manager dovrebbe essere Nuova ogni richiesta Http
  • Il contesto NON è thread safe quindi assicurati che ogni thread abbia il proprio contesto.
  • Lascia che EF memorizzi le cose dietro le quinte.
  • Test tempi di creazione del contesto. dopo diverse richieste Http. Hai ancora una preoccupazione?
  • Aspettare problemi se si memorizza il contesto in statico. qualsiasi tipo di accesso concorrente danneggerà e se si utilizzano le chiamate parallele AJAX, si presuppone una probabilità del 90% di problemi se si utilizza un singolo contesto statico.

For some performance tips, well worth a read

+1

Tra l'altro "Solo uno dei tanti esempi di UoW, questo di Julie Lerman" è di Tom Dykstra, non di Julie Lerman –

+0

Thx per la correzione Paul –

1

Il modo corretto o migliore pratica di usare variabile DbContext è con l'Uso.

using (var db = new MyEntities()) 
    { 
     return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault(); 
    } 

Il vantaggio è che molte cose sono fatte automaticamente per noi.Ad esempio, una volta completato il blocco di codice, viene chiamato lo smaltimento.

Per MSDN EF Working with DbContext

La durata del contesto inizia quando viene creata l'istanza e termina quando l'istanza è o smaltiti o garbage collection. Utilizzare utilizzando se si desidera che tutte le risorse che il contesto controlla siano eliminate alla fine del blocco. Quando lo usi, il compilatore crea automaticamente un blocco try/finally e chiama il blocco finally .