Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using on SQLDataReader

I know I asked a related question earlier. I just had another thought.

using (SqlConnection conn = new SqlConnection('blah blah'))
{
    using(SqlCommand cmd = new SqlCommand(sqlStatement, conn))
    {
        conn.open();

        // *** do I need to put this in using as well? ***
        SqlDataReader dr = cmd.ExecuteReader() 
        {
            While(dr.Read())
            {
                //read here
            }
        }
    }
}

The argument is that: Since the SqlDataReader dr object is NOT A NEW OBJECT LIKE THE connection or command objects, its simply a reference pointing to the cmd.ExecuteReader() method, do I need to put the reader inside a using. (Now based on my previous post, it is my understanding that any object that uses IDisposable needs to be put in a using, and SQLDataReader inherits from IDisposable, so I need to put it. Am I correct in my judgement?) I am just confused since its not a new object, would it cause any problems in disposing an object that simply is a reference pointer to the command?

Many thanks

like image 989
xeshu Avatar asked Aug 02 '10 10:08

xeshu


People also ask

What is the use of SqlDataReader?

The ADO.NET SqlDataReader class in C# is used to read data from the SQL Server database in the most efficient manner. It reads data in the forward-only direction. It means, once it read a record, it will then read the next record, there is no way to go back and read the previous record.

Do I need to close SqlDataReader?

You must ensure the Close method is called when you are through using the SqlDataReader before using the associated SqlConnection for any other purpose. The Close method may either be called directly or through the Dispose method, disposing directly or in the context of the using statement block.

What does SqlDataReader return?

As explained earlier, the SqlDataReader returns data via a sequential stream. To read this data, you must pull data from a table row-by-row Once a row has been read, the previous row is no longer available.

How do I get data from ExecuteReader?

To retrieve data using a DataReader, create an instance of the Command object, and then create a DataReader by calling Command. ExecuteReader to retrieve rows from a data source.


2 Answers

I think you are mistaken. The dr is a reference to the object returned by cmd.ExecuteReader, which is going to be a new object. In your example, nothing will dispose dr, so yes it needs to be in a using, or manually disposed.

Your judgement about IDisposable implementors needing to be in a using is not correct. They will function fine outside. A using statement is just syntactic sugar for a try ... finally. Things implementing IDisposable should have Dispose called, because they are signalling that they need to dispose certain state in a deterministic way.

Note that if you do not call Dispose, its not always a problem. Some objects also implement the finalizer, which will be triggered by the garbage collector. If they do not implement the finalizer, they might leave unmanaged memory unreclaimed. This will remain unreclaimed until your application closes. All managed memory is eventually reclaimed, unless it is not elligible for garbage collection.

Re-written:

using (SqlConnection conn = new SqlConnection('blah blah')) 
using(SqlCommand cmd = new SqlCommand(sqlStatement, conn)) 
{
   conn.open(); 
   using (SqlDataReader dr = cmd.ExecuteReader())
   { 
        while (dr.Read()) 
        { 
           //read here 
        } 
   } 
} 
like image 113
Adam Houldsworth Avatar answered Sep 20 '22 13:09

Adam Houldsworth


You should wrap the data reader in a using statement as the ExecuteReader method is creating a new data reader instance that should also be disposed of.

like image 32
Michael Arnell Avatar answered Sep 20 '22 13:09

Michael Arnell