Уже существует открытый DataReader, связанный с этой командой, который должен быть закрыт первым - PullRequest
7 голосов
/ 26 января 2012

Это код, который у меня есть.

/// <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;
}

Ответы [ 4 ]

9 голосов
/ 26 января 2012

Ваша проблема в том, что у вас явно есть один экземпляр m_ConStr;если метод вызывается одновременно, только один из них сможет использовать соединение, а другой потерпит неудачу с исключением, которое вы получаете.

Используйте этот шаблон вместо:

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

Другими словами, не определяйте соединение как глобальную переменную для класса.

5 голосов
/ 26 января 2012

Все ваши недолговечные IDisposable объекты там не имеют «использования».Таким образом, возможно, что вы сделали что-то вроде:

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

Но это не удаляет / не закрывает читатель.Если это так, добавьте «using»:

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

, что закрывает читатель независимо от того, как мы выйдемКоманды, соединения, считыватели и транзакции являются одноразовыми и должны обычно использовать «использование».

5 голосов
/ 26 января 2012

Я полагаю, вы можете использовать блок, чтобы обеспечить правильное удаление sqlconnection.

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

иначе вы также можете установить свойство MARS в вашем соединении, если вам нужно.

SqlConnection m_ConStr;= new SqlConnection("Server= serverName;Database=yourDatabase;
        MultipleActiveResultSets=true;");
1 голос
/ 26 января 2012

Вы пытаетесь запустить несколько наборов результатов действия (иначе MARS ).

На ум приходят два возможных решения:

  1. Открыть, открыть новыйсоединение в вашем GetContractResultSetByLead
  2. Включите MARS на сервере базы данных (описано в приведенной выше ссылке).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...