2017-05-29 141 views
1

我的代碼:System.InvalidOperationException:連接沒有關閉

private void button2_Click(object sender, EventArgs e) 
    { 
     sql.Open(); 

     string id = textBox1.Text; 
     string cadena = "DELETE FROM contacts WHERE id=" + id; 
     SqlCommand command = new SqlCommand(cadena, sql); 

     int cant; 
     cant = command.ExecuteNonQuery(); 

     if (cant == 1) 
     { 
      label4.Text = ""; 
      label5.Text = ""; 
      MessageBox.Show("Se ha eliminado"); 
     } 
     else 
      MessageBox.Show("No existe un artículo con el código ingresado"); 

     sql.Close(); 
     button2.Enabled = false; 
    } 

但已經宣佈的密切聯繫。

+1

不好的做法有習慣以奇怪的方式打你的代碼。不要保留全局連接對象。只需在本地使用一個,使用從您的配置加載的連接字符串創建它,使用它,然後銷燬。使用聲明是要查找的聲明。 – Steve

+0

代碼中有一個SQL注入攻擊向量,參數化您的查詢。 – t0mm13b

+0

也許使用(....),所以它會一直關閉 – urlreader

回答

0

檢查你的 sql.Close(); 它在我看來它包含在else塊中。

int cant; 
    cant = command.ExecuteNonQuery(); 
    sql.Close(); //Move it here. 
    if (cant == 1) 
    { 
     label4.Text = ""; 
     label5.Text = ""; 
     MessageBox.Show("Se ha eliminado"); 
    } 
    else 
    { 
     MessageBox.Show("No existe un artículo con el código ingresado"); 
    } 
    button2.Enabled = false; 

您應該在使用它們後關閉連接。

0

讓我們開始吧,從一開始,太多的罪上犯下:

//DONE: extract business logics, do not mix it with UI 
private bool DropContact(string id) { 
    //DONE: do not share single connection, but create when you want it 
    //DONE: wrap IDisposable into using 
    using (SqlConnection con = new SqlConnection(ConnectionStringHere)) { 
    con.Open(); 

    //DONE: make sql readable 
    //DONE: make sql parametrized 
    string cadena = 
     @"DELETE 
      FROM contacts 
      WHERE id = @prm_id"; 

    //DONE: wrap IDisposable into using 
    using (SqlCommand command = new SqlCommand(cadena, con)) { 
     //TODO: explict parameter type (int/string?) is a better then inplicit AddWithValue 
     command.Parameters.AddWithValue("@prm_id", id); 

     return command.ExecuteNonQuery() >= 1; 
    } 
    } 
} 
... 
private void button2_Click(object sender, EventArgs e) { 
    if (DropContact(textBox1.Text)) { 
    label4.Text = ""; 
    label5.Text = ""; 
    MessageBox.Show("Se ha eliminado"); 
    } 
    else { 
    MessageBox.Show("No existe un artículo con el código ingresado"); 
    } 

    button2.Enabled = false; 
} 
0

你似乎周圍共享sql對象。我認爲問題在於你在其他地方打開了一個連接,但從未關閉它。最終的結果是,你得到這個功能,當你調用此行它打破:

sql.Open(); 

檢查你的代碼,並找到你沒有正確關閉連接的地方。

此外,最好不要共享像這樣的連接對象,而是每次創建一個新連接對象。

0

您的代碼有兩個問題: 1)您可以在連接關閉之前得到異常。 爲了避免使用using語句,它非常舒適,因爲它有捕獲異常支持,或者您可以在finally塊中使用try-catch-finally語句和關閉連接。 2)每個連接只初始化SqlConnection對象(請檢查示例)。不要在不同的操作之間分享它,因爲它可能會導致你的意思。

using (SqlConnection con = new SqlConnection(connectionString)) 
{ 
    con.Open(); 
    using (SqlCommand command = new SqlCommand("your query", con)) 
    { 
    // output processing 
    } 
} 
0

您必須在重新打開之前檢查連接狀態(以防止全局使用它)。順便說一句(不要使連接公開或長時間打開)

if (sql != null && sql.State == ConnectionState.Closed) 
    sql.Open(); 

只是在試圖打開連接之前添加此條件。但更好地提高你的戰略。