I usually write my DataReader
code like this:
try { dr = cmd.ExecuteReader(CommandBehavior.SingleResult); while (dr.Read()) { // Do stuff } } finally { if (dr != null) { dr.Close(); } }
Is it safe to replace the try
and finally
with just a using
block around the DataReader
's creation? The reason I wonder is because in all the Microsoft examples I've seen they use a using for the connection but always explicitly call Close()
on the DataReader
.
Heres's an example from Retrieving Data Using a DataReader (ADO.NET):
static void HasRows(SqlConnection connection) { using (connection) { SqlCommand command = new SqlCommand( "SELECT CategoryID, CategoryName FROM Categories;", connection); connection.Open(); SqlDataReader reader = command.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { Console.WriteLine("{0}\t{1}", reader.GetInt32(0), reader.GetString(1)); } } else { Console.WriteLine("No rows found."); } reader.Close(); } }
CloseConnection to close your Connection object automatically when your DataReader closes. (Thanks for the lead in Wolfgang!) The using statement will close all of your objects and dispose of them for you. This is one of my personal favorites as it can make development a lot easier.
You should always call the Close method when you have finished using the DataReader object. If your Command contains output parameters or return values, they will not be available until the DataReader is closed.
Answers. Yes. When the using block ends, the connection automatically closes (That is what IDisposable is for). So, do not close the connection explicitly.
Note that disposing a SqlDataReader instantiated using SqlCommand. ExecuteReader() will not close/dispose the underlying connection. and the calling code just needs to dispose the reader thus: using(SqlDataReader reader = ExecuteReader(...))
Yes. using
calls Dispose. Calling Dispose on SqlDataReader closes it.
This is psuedo-code of SqlDataReader gleaned from Reflector:
public void Dispose() { this.Close(); } public override void Close() { if( !IsClosed ) CloseInternal(true); } private void CloseInternal(bool closeReader) { try { // Do some stuff to close the reader itself } catch(Exception ex) { this.Connection.Abort(); throw; } if( this.Connection != null && CommandBehavior.CloseConnection == true ) { this.Connection.Close(); } }
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