Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

There is already an open DataReader associated with this Command which must be closed first

Tags:

c#

datareader

This is the code I have.

/// <summary>
/// Method calls stored procedure and fills DataSet of contacts associated with Lead
/// </summary>
/// <param name="leadID">The ID associated with a Lead</param>
/// <returns>contacts list as DataSet</returns>
public static DataSet GetContactResultSetByLead(int leadID)
{
    SqlCommand Sqlmd = new SqlCommand("dbo.proc_contact");
    Sqlmd.CommandType = CommandType.StoredProcedure;
    Sqlmd.Parameters.Add("@LeadInfoID", SqlDbType.Int).Value = leadID;

    Sqlmd.Connection = m_ConStr;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);

    DataSet data = new DataSet();
    try
    {
        da.Fill(data);
    }

    finally
    {
        m_ConStr.Close();
    }

    return data;
}
like image 421
Marcus3329 Avatar asked Jan 26 '12 18:01

Marcus3329


People also ask

How do you fix there is already an open DataReader associated with this Command which must be closed first?

There is already an open DataReader associated with this Command which must be closed first. Have you got solution for this error? Hi, Try disconnecting and reconnecting to database before executing the query.

Is already an open DataReader associated with this connection which must be closed first?

Why do I get the error message 'There is already an open DataReader associated with this Connection which must be closed first. ' This is caused if you are attempting to use the same DataReader more than once in your code without closing the previous Datareader.

What is DataReader in Ado net?

In ADO.NET, a DataReader is a broad category of objects used to sequentially read data from a data source. DataReaders provide a very efficient way to access data, and can be thought of as a Firehose cursor from ASP Classic, except that no server-side cursor is used.


3 Answers

Your problem is that you apparently have one instance of m_ConStr; if the method is called concurrently only one of them will be able to use the connection and the other one will fail with the exception you are receiving.

Use this pattern instead:

using (SqlConnection conn  = new SqlConnection())
{
    conn.Open();
    Sqlmd.Connection = conn;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);
   //...etc
}

In other words, don't define connection as a global variable to the class.

like image 164
Icarus Avatar answered Nov 15 '22 21:11

Icarus


All of your short-lived IDisposable objects there are lacking a "using". By extension, then, it is possible that you've done something like:

var reader = anotherCommand.ExecuteReader();
...

But this does not dispose / close the reader. If this is the case, add "using":

using(var reader = anotherCommand.ExecuteReader()) {
    ...
}

Which closes the reader, regardless of how we exit. Commands, connections, readers and transactions are all disposable and should all usually use "using".

like image 21
Marc Gravell Avatar answered Nov 15 '22 21:11

Marc Gravell


i suggest You can using block to ensure proper disposing of sqlconnection.

using (SqlConnection conn  = new SqlConnection())
{
    conn.Open();
    Sqlmd.Connection = conn;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);
    Dataset ds = new Datasest
    da.Fill(ds)
}

the other way is you can also set MARS property in your connection, if you needed.

SqlConnection m_ConStr;= new SqlConnection("Server= serverName;Database=yourDatabase;
        MultipleActiveResultSets=true;");
like image 21
Ravi Gadag Avatar answered Nov 15 '22 23:11

Ravi Gadag