问题
My DBA says that there are way too many connection open and he thinks it is my code in .net that is leaving them open.
I am using LINQ querys and EF code first.
Example Method:
public List<Stuff> GetStuff()
{
var db = new DBContext();
var results = db.stuff.toList();
return results;
}
Do I need to dispose the db var once I am done? My understanding is that I didn't need to in EF and LINQ. Please point me to a Microsoft documentation about managing connection in code or best practices for LINQ/EF and db connections
Update:
I added
db.Connection.Close();
db.Dispose();
and I still see the open connection in SQL after the two lines were executed. Is there a reason why it wouldn't close when I force it to close?
回答1:
By default DbContext automatically manages the connection for you. So you shouldn't have to explicitly call Dispose.
Blog post on the subject: Link
But I believe not disposing can cause performance issues if you're processing a lot of requests. You should add a using statement to see whether or not it's causing a problem in your case.
回答2:
You should listen to your DBA! Yes, use a using
. Do not leave connections open unnecessarily. You should connect, do your business with the db, and close that connection, freeing it up for another process. This is especially true in high volume systems.
Edit. Let me further explain with my own experiences here. In low volume processing, it probably isn't an issue, but it's a bad habit not to dispose of something explicitly or not-wrap it in a using
when it clearly implements IDisposable
.
In high-volume situations, this is just asking for disaster. Sql server will allot so many connections per application (can be specified in the connection string). What happens is processes will spend time waiting for connections to free up if they're not promptly closed. This generally leads to timeouts or deadlocks in some situations.
Sure, you can tweak Sql server connection mgmt and such, but everytime you tweak a setting, you're making a compromise. You must consider backups running, other jobs running, etc. This is why a wise developer will listen to their DBA's warnings. It's not always all about the code...
回答3:
I just asked this same question over on Programmers.SE. Robert Harvey gave a great answer.
In general, you don't need to use Using statements with Entity Framework data contexts. Lazy collections is one of the reasons why.
I encourage you to read the entire answer on Programmers.SE as well as the links Robert provides in the answer.
回答4:
The entity framework uses, as far as i know, connection pooling by default to reduce the overhead of creating new connections everytime. Are the connections closed when you close your application?
If so, you could try to decrease the Max Pool Size in your connection string or disable connection pooling entirely. See here for a reference of possible options in your connection string.
回答5:
Yes, if your method defines a Unit of Work; no, if something more primitive. (P.S. something somewhere in your code should define a Unit of Work, and that thing should be wrapped in a using (var context = new DbContext()) {}
or equivalent.)
And if you belong to the school of thought that your DbContext
is your Unit of Work, then you'll always be wrapping that bad boy with a using
block: the local caching of data previously fetched during the context lifetime together with the SaveChanges
method act as a sort of lightweight transaction, and your Dispose
(without calling SaveChanges
) is your Rollback (whereas your SaveChanges
is your Commit).
回答6:
Check this out, here's a standard protocol on how to use IDisposable objects. https://msdn.microsoft.com/en-us/library/yh598w02.aspx
It says:
"As a rule, when you use an IDisposable object, you should declare and instantiate it in a using statement."
As they have access to unmanaged resources, you should always consider a "using" statement.
来源:https://stackoverflow.com/questions/28598228/do-i-need-to-force-a-dispose-after-a-linq-query