The database access classes that implement IDbConnection, IDbCommand and IDataReader all implement IDisposable, but obviously the Command and the Reader are dependent on the Connection. My question is, do I have to Dispose() of each these objects individually or will disposing of the Connection object dispose of the others too ?
That is, can I do this and guarantee I’m not risking leaving any unmanaged resources not being freed:
using (IDbConnection conn = GetConnection())
{
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = " ..... ";
IDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
}
}
Or do I have to do this instead:
using (IDbConnection conn = GetConnection())
{
using (IDbCommand cmd = conn.CreateCommand())
{
cmd.CommandText = " ..... ";
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
}
}
}
}
Or is this implementation dependent, so it would potentially work using one database’s provider but not for another’s ?
Best policy is to use all ADO.NET objects in using blocks- full stop.
A little Reflector-ing on various ADO.NET objects shows that things will more or less be dropped on the floor if not Closed/Disposed. The effect of that will depend a lot on which providers you’re using- if you’re using something with unmanaged handles underneath (ODBC, OleDb, etc), you’re probably going to leak memory, as I didn’t see anything in the way of finalizers. If it’s an all-managed provider (eg, SqlClient), it’ll eventually get cleaned up, but depending on which objects you’re holding onto, you could end up keeping resources in use on the DB server a lot longer than you want.