2012-01-26 57 views
7

這是我的代碼。已經有一個開放的DataReader與這個Command相關聯,必須先關閉

/// <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'? –

+0

更改此行Sqlmd.Parameters.Add(「@ LeadInfoID」,SqlDbType.Int).Value = leadID;到Sqlmd.Parameters.AddWithValue(「@ LeadInfoID」,leadID);如果您想保留全局連接,請檢查該連接的狀態(如果已打開),然後在使用它之前關閉它。減少你的代碼並使用有意義的變量名字....!將你的Connection連接到using(){} – MethodMan

+1

在da.Fill調用期間將執行Sqlmd。 m_ConStr似乎是一個名字很差的變量 - 它看起來是指連接本身,而不是連接字符串。 – RQDQ

回答

9

你的問題是,你顯然有一個m_ConStr實例;如果同時調用該方法,則只有其中一個將能夠使用該連接,而另一個將失敗,並且收到異常。

使用這個模式來代替:

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

換句話說,不要定義連接爲一個全局變量的類。

+0

「沒有定義連接爲一個全局變量」:但那麼如何避免隨時創建並打開一個連接,我必須執行一個sp。 在我的情況下,我必須執行很多sp,並且沒有instanciate一個連接,另一種方法是每次創建並打開。任何提示? – ff8mania

1

你試圖運行多個actice結果集(又名MARS)。

兩個可能的解決方案浮現在腦海中:

  1. 開開你的GetContractResultSetByLead一個新的連接
  2. 您的數據庫服務器(在上面的鏈接描述)上啓​​用MARS。
+0

您也可以嘗試在web.config添加到連接字符串這樣的:的connectionString =「MultipleActiveResultSets = TRUE;用戶= ...」 – Nestor

5

我建議你可以使用塊,以確保SqlConnection的適當的優化配置。

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

另一種方式是你也可以在你的連接中設置MARS屬性,如果你需要的話。

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

應該在本地聲明連接(如果您使用共享實例,則會發生各種副作用)。另外,爲什麼不只是使用using語句來管理連接的生命週期? – RQDQ

+1

這也是不錯的建議:)確定將編輯它:) –

+1

非常感謝 – Marcus3329

5

您所有的短期IDisposable對象都缺少「使用」。那麼,通過擴展,有可能你做了類似的事情:

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

但是這不會處理/關閉閱讀器。如果是這種情況,請添加「使用」:

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

無論我們如何退出,它都會關閉閱讀器。命令,連接,讀者和交易都是一次性的,並且通常都應該使用「使用」。

相關問題