8

私は次のようなsqlConnectionマネージャークラスを持っています:

public class SQLConn {
  public string connStr = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];

  private SqlConnection sqlConn;

  public SqlConnection Connection()
  {
      sqlConn = new SqlConnection(connStr);

      return sqlConn;
  }

  public void Open()
  {
        sqlConn .Open();
  }
}

次のような'using'ステートメントで関数を使用する場合:

var conn = new SQLConn();

using (conn.Connection()) 
{ 
    String query = "Select * from table";
    objSql = new SqlCommand(query, conn.Connection());      

    conn.Open(); 
    DoSomething(); 
}

usingステートメントconn.Connection()はSqlConnectionオブジェクトを返すため、接続を自動的に破棄しますか?または、SqlConnクラスにIDisposableとカスタムDisposeメソッドを実装する必要がありますか?

これはまったく良い方法ですか?レガシーコードを使用していますが、まだORMを使用できませんが、この既存のパターンを単純化してSQL接続を管理/作成する方法はありますか?

4

8 に答える 8

12

ステートメントは、式のusing最終的な型、つまり から返されるものを調べます.Connection()。これが何かを返す場合はIDisposable、問題ありません。

コンパイラは、間違っているかどうかを教えてくれます ;-p (そうでないusingものでは使用できませんIDisposable)。

おそらく、 2 つの接続を作成している場所に注意する必要があります。

using (var c = conn.Connection()) // <==edit
{ 
    String query = "Select * from table";
    objSql = new SqlCommand(query, c); // <==edit

    c.Open(); 
    DoSomething(); 
}

そしておそらく:

public SqlConnection Connection()
{
  if(sqlConn == null) sqlConn = new SqlConnection(connStr); // <== edit
  return sqlConn;
}
于 2009-05-27T10:33:10.603 に答える
5

それは機能しusing {}ますが、その後、Disposed SqlConnection を内部的に保持する sqlConn が残ります。あまり役に立たない状況

于 2009-05-27T10:36:46.600 に答える
1

上記の内容を明確にするために:

using で使用する必要があるオブジェクトは、using ステートメントの最後で破棄する必要があります。したがって、コンパイラは、その型オブジェクトで使用されていることを確認したときに、型が IDisposable インターフェイスを実装していることを確認する必要があります。

于 2012-02-27T20:16:47.757 に答える
1

あなたのコードは間違っています!

次のようにする必要があります。

Dim conn as New SQLConn();
Dim sqlConnection New SQLConnection();

sqlConnection = conn.Connection();

using (sqlConnection) 
{ 
    String query = "Select * from table";
    objSql = new SqlCommand(query, sqlConnection);      

    conn.Open(); 
    DoSomething(); 
}

そうすれば、 using ステートメントは最後に接続を破棄します。

于 2009-05-27T10:37:45.460 に答える
1

見出しの質問に答えるには、「using」で使用しているオブジェクトのクラスに IDisposable を実装する必要があります。そうしないと、コンパイル時エラーが発生します。

次に、はい、「使用」すると、ブロックの最後で SqlConnection が破棄されます。「使用」を「try-finally」と考えてください。「finally」ブロックには Dispose() への暗黙の呼び出しがあります。

最後に、よりクリーンなコードは次のようになります。

using( SqlConnection = new SqlConnection( connStr ) {
    // do something
}

少なくともコードの読者は、SQLConn オブジェクトが破棄された接続への参照を保持していることを Henk Holterman が指摘したように、頭を悩ませる必要はありません。

于 2009-05-27T10:58:45.993 に答える
0

いいえ、返されたオブジェクトが IDisposable である限り、必要ありません。

返されたオブジェクトは IDisposable を実装する必要はありませんが、その場合、using ブロックは何の役にも立たなくなります。

于 2009-05-27T10:32:17.297 に答える
0

接続は適切に閉じられるようですが、これはお勧めしません:

リソース オブジェクトをインスタンス化してから、変数を using ステートメントに渡すことができますが、これはベスト プラクティスではありません。この場合、制御が using ブロックを離れた後もオブジェクトはスコープ内に残りますが、おそらくアンマネージ リソースにアクセスできなくなります。つまり、完全に初期化されなくなります。using ブロックの外側でオブジェクトを使用しようとすると、例外がスローされる危険があります。このため、通常は using ステートメントでオブジェクトをインスタンス化し、そのスコープを using ブロックに限定することをお勧めします。

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

于 2009-05-27T10:39:45.143 に答える
0

MSDNから:

using ステートメントに提供されるオブジェクトは、IDisposable インターフェイスを実装する必要があります。

Dispose() を呼び出す必要はありませんが、using ステートメントが暗黙的にこれを行います。

于 2009-05-27T10:34:48.790 に答える