11

このヘルパー メソッドをこのように書いても安全ですか? 常に接続を閉じますか?すべてがうまくいけば理解できますが、 ExecuteReader がスローされても接続を閉じますか?

    public static IEnumerable<DbDataRecord> ExecuteSelect(string commandText, DbConnection conn)
    {
        using (DbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = commandText;
            conn.Open();
            using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                foreach (DbDataRecord record in reader) { yield return record; }
            }
        }
    }
4

5 に答える 5

9

はい、例外をスローしても接続を閉じます。指定せずCommandBehavior.CloseConnectionに接続を閉じた場合、呼び出し元のコードはリーダーの内容にアクセスできません。

また、MSDNから:

コマンドが実行されると、関連する DataReader オブジェクトが閉じられると、関連する Connection オブジェクトが閉じられます。

作業が完了したら、リーダーが閉じていることを確認する必要があります。このすべての良い点は、using ステートメントをラップしていて、使用していないtry/catch/finally場合、リーダーが閉じられ、データベース接続が閉じられることです。

于 2012-05-09T15:35:09.047 に答える
0

質問は、接続を閉じることに関連していることを知っています。ただし、接続は破棄されません。using接続自体を破棄するには、それもブロックで囲む必要があります。

using (DBConnection conn = new ...)
{
    using (DbCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = commandText;
        conn.Open();
        using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            foreach (DbDataRecord record in reader) { yield return record; }
        }
    }
}

更新これは興味深い質問だと思ったので、次のテストを書きました。

string connString = @"Data Source=.\SQLEXPRESS;Initial Catalog=msdb;Integrated Security=True;";
SqlConnection conn = new SqlConnection(connString);

try
{
using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "select  from MSdbms"; 
        conn.Open();
        Console.WriteLine(conn.State);
        using (IDataReader reader = cmd.ExecuteReader())//Will throw an exception - Invalid SQL syntax -see setting CommandText above
        {
            Console.WriteLine("here");
        }
    }
}
catch(Exception ex)
{  Console.WriteLine(conn.State); } //prints Open

using (IDataReader reader = cmd.ExecuteReader())が次のように変更されると、 Closedusing (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))が出力されます。心に留めておくべきこと。

于 2012-05-09T15:44:05.583 に答える
0

はい、そうです(あなたがやっているようにusingブロック内で)。ただし、データにアクセスするには、その内容を反復処理する代わりに、While DbDataReader.read を使用することをお勧めします。

于 2012-05-09T15:35:02.987 に答える