2012-01-26 30 views
7

これは私のコードです。このコマンドに関連付けられている開いているDataReaderが既にあります。最初に閉じる必要があります。

/// <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)に設定します。グローバル接続を維持する場合は、開いている場合はその接続の状態を確認し、使用する前に閉じます。あなたのコードを改訂し、わかりやすい名前を使用してください....! using(){} – MethodMan

+1

の周囲に接続をラップするda.Fill呼び出し中にSqlmdが実行されます。 m_ConStrは名前のない変数のように見えます。接続文字列ではなく、接続自体を参照するように見えます。 – RQDQ

答えて

9

あなたの問題は明らかにm_ConStrという1つのインスタンスがあることです。メソッドが同時に呼び出された場合、そのうちの1つだけが接続を使用することができ、もう1つは受け取っている例外で失敗します。

ではなく、このパターンを使用します。つまり

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

を、クラスにグローバル変数として接続を定義していません。

+0

"接続をグローバル変数として定義しないでください。 spを実行する必要があるときはいつでも接続を作成して開くことができます。 私の場合、私は多くのspを実行しなければならず、1つの接続をインスタンス化することなく、代わりに、毎回作成して開くことです。何かヒント? – ff8mania

1

複数のアクチス結果セット(別名MARS)を実行しようとしています。

2つの解決策が頭に浮かぶ:

  1. オープンはあなたのGetContractResultSetByLead
  2. に新しい接続を開く(上記のリンクを参照)、データベース・サーバ上のMARSを有効にします。
+0

また、これをweb.configの接続文字列に追加することもできます。connectionString = "MultipleActiveResultSets = True; user = ..." – Nestor

5

私はあなたがsqlconnectionの適切な廃棄を確実にするためにblockを使用することができます。

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

thatsも良い提案:) okはそれを編集します:) –

+1

ありがとう – Marcus3329

5

あなたの短命のIDisposableオブジェクトには「使用」がありません。

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

しかし、これは/処分リーダーを閉じない:拡張することで、その後、あなたのようなものをやったことがあります。このような場合は、「使用」を追加:リーダーを閉じ

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

を、関係なく、どのように我々出口。コマンド、接続、読者、トランザクションはすべて使い捨てで、通常はすべて「使用」する必要があります。

関連する問題

 関連する問題