2012-06-15 42 views
5

Tại sao mã này ném một ngoại lệ hoạt động không hợp lệ?InvalidOperationException Kết nối không được đóng. Trạng thái hiện tại của kết nối đang mở

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

+1

Có lẽ bạn đã mở kết nối của bạn trước? – Zbigniew

+2

Tôi nghĩ rằng gốc của vấn đề là trong trường hợp của SqlCommand khởi tạo tại constructor lớp. Có được var này trong tất cả các mã của bạn có thể dễ dàng bị lạm dụng và dẫn đến lỗi khó chịu trong các phần khác của mã của bạn – Steve

+1

http://stackoverflow.com/a/9707060/4068 –

Trả lời

7

Bạn đang cố gắng để mở một kết nối đã được mở, kết quả này trong ngoại lệ.

Giải pháp 1 (đề nghị):

Kiểm tra mã của bạn, rà soát tất cả các phần nơi cmd.Connection kết nối được mở ra và đảm bảo rằng nó luôn luôn đóng đúng cách.

Giải pháp 2 (quick'n'dirty sửa chữa):

trước dòng

cmd.Connection.Open(); 

thêm mã kiểm tra/dọn dẹp sau:

if (cmd.Connection.State == ConnectionState.Open) 
{ 
    cmd.Connection.Close(); 
} 
+1

Bleh! Freakin 'noobie sai lầm. – jp2code

+0

Vâng, điều này có thể thực hiện công việc, tuy nhiên mã OP làm sáng tỏ dòng ExecuteNonQuery, không phải là Connection.Open – Steve

3

Có rất ít nhu cầu giữ các đối tượng Sql * ở cấp lớp, đặc biệt dựa trên những gì bạn đang hiển thị. Bạn cũng sẽ mất những lợi ích của việc kết nối tổng hợp bằng cách cố gắng tự làm điều đó.

Với phương pháp này, bạn loại bỏ khả năng lỗi của bạn vì bạn không chia sẻ bất kỳ đối tượng

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; 
} 
+1

Xem thêm: http://stackoverflow.com/a/9707060/4068 –

+0

Lý do duy nhất tôi tạo ra nó theo cách này để một số số phần từ một yêu cầu có thể chia sẻ cùng một giao dịch. Tôi đã tìm thấy một cách tốt hơn để làm điều đó, tuy nhiên, vì vậy tôi có thể (có lẽ nên) mương phương pháp cũ này anyway. Cảm ơn. – jp2code

Các vấn đề liên quan