InvalidOperationException Соединение не было закрыто. Текущее состояние соединения открыто

Почему этот код вызывает исключение недопустимой операции?

private SqlCommand cmd; // initialized in the class constructor

public void End(string spSendEventNotificationEmail) {
  try {
    cmd.CommandText = spSendEventNotificationEmail;
    cmd.Parameters.Clear();
    cmd.Parameters.Add("@packetID", SqlDbType.Int).Value = _packetID;
    cmd.Parameters.Add("@statusID", SqlDbType.Int).Value = _statusID;
    cmd.Parameters.Add("@website", SqlDbType.NVarChar, 100).Value = Tools.NextStep;
    cmd.Connection.Open();
    cmd.ExecuteNonQuery();
  } finally {
    cmd.Connection.Close();
    cmd.Parameters.Clear();
    cmd.Dispose();
  }
  endCall = true;
}

InvalidOperationException

 Austin Salonen15 июн. 2012 г., 19:26
 Steve15 июн. 2012 г., 17:35
Я думаю, что корень проблемы в экземпляре SqlCommand, инициализированном в конструкторе классов. Наличие этой переменной во всем вашем коде может быть легко использовано неправильно и привести к неприятным ошибкам в других частях вашего кода.
 Zbigniew15 июн. 2012 г., 17:30
Может быть, вы открыли свое соединение раньше?

Ответы на вопрос(2)

Решение Вопроса

Вы пытаетесь открыть соединение, которое уже открыто, это приводит к исключению.

Solution 1 (recommended):

Проверьте свой код, проверьте все части, гдеcmd.Connection соединение открыто и убедитесь, что оно всегда закрыто должным образом.

Solution 2 (quick'n'dirty fix):

перед линией

cmd.Connection.Open();

добавьте следующий код проверки / очистки:

if (cmd.Connection.State == ConnectionState.Open)
{
    cmd.Connection.Close();
}
 jp2code15 июн. 2012 г., 17:35
BLEH! Freakin & APOS; нуби ошибки.
 15 июн. 2012 г., 17:38
Ну, это может сделать работу, однако код OP выделяет строку ExecuteNonQuery, а не Connection.Open

Существует очень небольшая потребность в сохранении объектов Sql * на уровне класса, особенно в зависимости от того, что вы показываете. Вы также потеряете преимущества пула соединений, если попытаетесь сделать это самостоятельно.

С помощью этого метода вы устраняете вероятность ошибки, потому что вы не делитесь какими-либо объектами.

private readonly _connectionString = "...";

public void End(string spSendEventNotificationEmail) {
  using(var conn = new SqlConnection(_connectionString))
  using(var cmd = conn.CreateCommand())
  {
    cmd.CommandText = spSendEventNotificationEmail;
    cmd.Parameters.Add("@packetID", SqlDbType.Int).Value = _packetID;
    cmd.Parameters.Add("@statusID", SqlDbType.Int).Value = _statusID;
    cmd.Parameters.Add("@website", SqlDbType.NVarChar, 100).Value = Tools.NextStep;
    conn.Open();
    cmd.ExecuteNonQuery();
  }
  endCall = true;
}
 jp2code15 июн. 2012 г., 21:32
Единственная причина, по которой я изначально создал этот способ, заключалась в том, что несколько номеров деталей из одного запроса могли использовать одну и ту же транзакцию. Однако я нашел лучший способ сделать это, так что я мог бы (вероятно, должен) отказаться от этого старого метода в любом случае. Благодарю.
 15 июн. 2012 г., 19:26
Смотрите также:stackoverflow.com/a/9707060/4068

Ваш ответ на вопрос