Ho abbastanza semplice WinForms/Entity Framework programma (V6) che:Entity Framework - Lasciando DB contesto aperto vs continuamente ricreando
- interroga un database per popolare gli elementi del modulo
- Al clic dell'utente, ri-interroga il database per ottenere le informazioni pertinenti
- 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?
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. –
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
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. –