2012-01-26 37 views
7

Đây là mã tôi có.Đã có một DataReader mở được kết hợp với Lệnh này phải được đóng trước tiên

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

'm_ConStr' là gì? –

+0

thay đổi dòng này Sqlmd.Parameters.Add ("@ LeadInfoID", SqlDbType.Int) .Value = leadID; tới Sqlmd.Parameters.AddWithValue ("@ LeadInfoID", leadID); Nếu bạn muốn giữ kết nối toàn cầu, hãy kiểm tra trạng thái của kết nối đó nếu mở rồi đóng nó trước khi sử dụng nó. XÁC NHẬN MÃ CỦA BẠN VÀ SỬ DỤNG CÁC BIẾN ĐỔI TIỆN ÍCH ....! Quấn kết nối của bạn xung quanh một using() {} – MethodMan

+1

Sqlmd sẽ được thực hiện trong suốt cuộc gọi. m_ConStr dường như là một biến được đặt tên kém - nó dường như đề cập đến chính kết nối đó chứ không phải là chuỗi kết nối. – RQDQ

Trả lời

9

Vấn đề của bạn là bạn dường như có một phiên bản m_ConStr; nếu phương thức này được gọi đồng thời chỉ một trong số chúng sẽ có thể sử dụng kết nối và một phương thức khác sẽ không thành công với ngoại lệ bạn nhận được.

Sử dụng mô hình này để thay thế:

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

Nói cách khác, không xác định kết nối như là một biến toàn cầu đến lớp.

+0

"không xác định kết nối dưới dạng biến toàn cầu": nhưng sau đó cách tránh tạo và mở một kết nối bất cứ lúc nào tôi phải thực hiện một sp. Trong trường hợp của tôi, tôi đã thực hiện rất nhiều sp, và không có instanciate một kết nối, thay thế là tạo và mở mọi lúc. Bất kỳ gợi ý nào? – ff8mania

1

Bạn đang cố gắng chạy nhiều bộ kết quả hành động (aka MARS).

Hai giải pháp khả thi tôi suy nghĩ:

  1. mở mở một kết nối mới trong GetContractResultSetByLead bạn
  2. Enable MARS trên máy chủ cơ sở dữ liệu của bạn (được mô tả trong các liên kết ở trên).
+0

Bạn cũng có thể thử thêm điều này vào web.config vào chuỗi kết nối: connectionString = "MultipleActiveResultSets = True; user = ..." – Nestor

5

tôi đề nghị Bạn có thể sử dụng khối để đảm bảo xử lý thích hợp kết nối sqlconnection.

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

cách khác là bạn cũng có thể đặt thuộc tính MARS trong kết nối của mình, nếu cần.

SqlConnection m_ConStr;= new SqlConnection("Server= serverName;Database=yourDatabase; 
     MultipleActiveResultSets=true;"); 
+2

Kết nối phải được khai báo cục bộ (tất cả các loại tác dụng phụ sẽ xảy ra nếu bạn sử dụng một phiên bản dùng chung). Ngoài ra, tại sao bạn không chỉ sử dụng một tuyên bố sử dụng để quản lý tuổi thọ của kết nối? – RQDQ

+1

thats cũng gợi ý tốt :) ok sẽ chỉnh sửa nó :) –

+1

Cảm ơn bạn rất nhiều – Marcus3329

5

Tất cả các đối tượng IDisposable ngắn ngủi của bạn đang thiếu "đang sử dụng". Bằng cách gia hạn, khi đó, có thể bạn đã thực hiện một số việc như:

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

Nhưng điều này không hủy bỏ/đóng trình đọc. Nếu trường hợp này xảy ra, hãy thêm "using":

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

Đóng trình đọc, bất kể chúng ta thoát ra sao. Các lệnh, kết nối, độc giả và giao dịch đều dùng một lần và tất cả thường sử dụng "sử dụng".

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