7

このコードが無効な操作例外をスローするのはなぜですか?

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

4

2 に答える 2

7

すでに開いている接続を開こうとすると、例外が発生します。

解決策 1 (推奨):

コードを検査し、cmd.Connection接続が開かれているすべての部分を確認し、常に適切に閉じられていることを確認してください。

解決策 2 (簡単な修正):

行の前

cmd.Connection.Open();

次のチェック/クリーンアップ コードを追加します。

if (cmd.Connection.State == ConnectionState.Open)
{
    cmd.Connection.Close();
}
于 2012-06-15T15:30:04.300 に答える
5

特に表示内容に基づいて、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;
}
于 2012-06-15T17:22:10.200 に答える