2014-08-28 10 views
6

Ho abbastanza semplice WinForms/Entity Framework programma (V6) che:Entity Framework - Lasciando DB contesto aperto vs continuamente ricreando

  1. interroga un database per popolare gli elementi del modulo
  2. Al clic dell'utente, ri-interroga il database per ottenere le informazioni pertinenti
  3. esegue i calcoli su tali informazioni e visualizza all'utente

Essendo un novizio EF, ho cercato di seguire gli esempi di cose che ho' ho trovato on-line e sono venuto con qualcosa di abbastanza semplice per il popolamento/interrogazione lungo le linee di:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    Using ctx As New MyEntities 
      <Query DB to populate initial values for first combobox> 
    End Using 
End Sub 

Private Sub cboVal1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboVal1.SelectedIndexChanged 
    Using ctx As New MyEntities 
     <Queries to populate the other controls based upon user selections> 
    End Using 
End Sub 

Private Sub Button_Press(sender As Object, e As EventArgs) Handles MyButton.Click 
    Using ctx As New MyEntities 
     <Queries to get data, based upon user selections for calculations> 
    End Using 
End Sub 

Quello che sto scoprendo è che la parte che sembra essere a rallentare il mio programma (e favore correggetemi se sbaglio su questo - Come ho detto, io sono un principiante) è che sto ristabilendo una nuova connessione DB ogni volta che uso il:

Using ctx As New MyEntities 
    ... 
End Using 

nel mio codice .

Quindi, quello che sto pensando di fare è avere una variabile a livello di modulo ctx as MyEntities - Per stabilire la connessione su form-load e chiudere la connessione sulla chiusura del modulo e continuare a utilizzare lo stesso in tutto ... qualcosa lungo le linee di:

Dim ctx as MyEntities 

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    ctx = New MyEntities 

    <Query ctx to populate initial values for first combobox> 
End Sub 

Private Sub cboVal1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboVal1.SelectedIndexChanged 
    <Queries ctx to populate the other controls based upon user selections> 
End Sub 

Private Sub Button_Press(sender As Object, e As EventArgs) Handles MyButton.Click 
    <Queries ctx to get data, based upon user selections for calculations> 
End Sub 

Private Sub Main_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing 
    ctx.Dispose() 
    ctx = Nothing 
End Sub 

Quando sono passato le cose su cui lavorare in questo modo, sembra avere maggiore velocità in modo drammatico, mi rendo conto che mi lascia aperta la possibilità di una possibile effettuare cattive modifiche al DB, ma questo è un piccolo progetto che non esegue alcun aggiornamento, basta interrogare ... È una soluzione ragionevole o è un modo pericoloso di fare le cose?

+1

In generale si dovrebbe utilizzare un DBContext in un modo di unità di lavoro, altrimenti i dati possono diventare obsoleti mentre il contesto DB memorizza nella cache le entità, ad es. se si esegue la stessa query due volte, verrà colpito solo una volta il DB. Ho usato EF estensivamente e non ho mai trovato che usare i contesti in questo modo fosse costoso. Vorrei fare ulteriori indagini per vedere dove è il tuo rallentamento. –

+1

Sono anche curioso di sapere se ricreare l'ereditarietà di DBContext è costoso. Ho creato un repository prima in cui ogni funzione nel repository utilizza la propria istanza di DBContext. Non sembra che ci siano problemi lì, ma di nuovo l'app non è stata molto intensiva di dati. Guarda questo articolo sull'implementazione del modello Unit of Work con EF: http: //www.asp.net/mvc/tutorial/get-started-with-ef-5-using-mvc-4/implementazione-the-repository-and-unit-of-work-patterns-in-un-asp-net-mvc-application – erdinger

+1

Se non è necessario modificare i dati caricati (e scriverli di nuovo nel database), è necessario prendere in considerazione la disattivazione del changetracking del contesto (ctx.Configuration.AutoDetectChanges = false). Questo dovrebbe darti un notevole aumento delle prestazioni. –

risposta

5

Le connessioni di database vengono generalmente raggruppate in un pool di connessioni con qualsiasi strumento di query moderno. Questo assomiglierà molto al pool di thread; verrà aperto un certo numero di connessioni e ogni volta che viene creato un nuovo contesto e viene richiesta una connessione verrà utilizzato esclusivamente una delle connessioni esistenti. Quando il contesto viene eliminato, la connessione non verrà chiusa, verrà solo restituita al pool di connessioni.

Per questo motivo non è necessario provare a mantenere in vita i contesti per lunghi periodi di tempo. Usali per una singola operazione.

Ovviamente è possibile disabilitare il pool di connessioni se si desidera esplicitamente che non accada, ma è piuttosto raro che ciò si verifichi.

+0

Grazie, Servire !!!! - Quindi, per capire, quello che stai dicendo è che la mia prima colluttazione non è affatto così costosa come pensavo da quando quella connessione rimarrà aperta per tutto il tempo e rimarrà in piscina fino alla fine dell'applicazione, sto capendo quello correttamente? –

Problemi correlati