I have a fairly simple Winforms / Entity Framework (v6) program that:
Being an EF newbie, I've tried to follow examples of things I've found online and have come up with something fairly simple for the populating / querying along the lines of:
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
What I'm discovering is that the part that seems to be slowing down my program (and please correct me if I'm wrong about this - As I said, I am a newbie) it that I'm re-establishing a new DB connection each time I use the:
Using ctx As New MyEntities
...
End Using
in my code.
So, what I am thinking about doing is to have a form-level variable ctx as MyEntities
- To establish the connection on form-load and close the connection on form closing and to keep using the same one throughout... something along the lines of:
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
When I switched things to work this way, it seems to have increased speed dramatically, I'm aware that it leaves me open to the possibility of possibly making bad changes to the DB, but this is a small project that doesn't do any updating - just querying... Is this a reasonable solution or am is this a dangerous way to do things?
Don't dispose DbContext objects. Although the DbContext implements IDisposable , you shouldn't manually dispose it, nor should you wrap it in a using statement. DbContext manages its own lifetime; when your data access request is completed, DbContext will automatically close the database connection for you.
If we have multiple DbContexts with the same connection then the connection should be disposed of whenever the first closes the connection. Similarly things should happen for the mixed mode of ADO.Net and Entity Framework. DbContext always closes the connection when it is disposed of.
This is usually caused by different threads using the same instance of DbContext, however instance members are not guaranteed to be thread safe. When concurrent access goes undetected, it can result in undefined behavior, application crashes and data corruption.
So if you have more than one DbContext with the same connection whichever context is disposed first will close the connection (similarly if you have mixed an existing ADO.NET connection with a DbContext, DbContext will always close the connection when it is disposed).
Database connections are generally going to be pooled in a connection pool with just about any modern querying tool. This will look much like the thread pool does; some number of connections will be opened and whenever a new context is created and requests a connection it will be given exclusive use of one of the existing connections. When the context is disposed the connection won't be closed, it'll just be returned to the connection pool.
Because of this there is no need to try to manually keep contexts alive for long periods of time. Use them for just a single operation.
Of course it's possible to disable connection pooling if you explicitly don't want it to happen, but there is pretty rarely cause for doing that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With