3

using ブロックの外側で変数を宣言する必要がある場合があるクエリ (独自のコマンドまたは書き込み parameters.clear() が必要) のすべてに using ステートメントを記述するのは非常に面倒です。オブジェクトを破棄しないバージョンに比べて、信じられないほど煩わしく、非常に汚く見えます。

処分する必要がありますか?そうしないとどうなりますか?オブジェクトにそのインターフェイスがある場合は、オブジェクトを破棄することをお勧めします。

4

2 に答える 2

5

Reflector を一目見ただけで、PreparableStatement で CloseStatement() を呼び出してから、System.ComponentModel.Component を含むそのスーパークラスで Dispose() を呼び出しているように見えます。チェーンのどこかで、接続ストリームにコマンドを書き込む NativeDriver.CloseStatement32(id) を呼び出します。

それは私がスキップしたい種類のものではありません。なぜそれを危険にさらすのですか?

これは、自分の考え方を調整する必要があるときの 1 つです。「汚れている」と思われるかもしれませんがusing、ギア システムに新鮮なオイルがきらめくように、それは実際には汚れていないことの表れです。それを隠すために抽象化を書くことができるかもしれませんが、それを取り除くべきではありません。

于 2010-05-24T18:48:16.143 に答える
2

ASP.NET をターゲットにしている場合は、Connect() メソッド (存在する場合) をセットアップして、ページのアンロード時に実行するファイナライザーもセットアップできます。このトリックは、不足している接続プールに問題がある場合にも役立ちます。

Test メソッドのように、型保証されたパラメーターを使用して SQL コマンドを簡単に記述できるように、Exec メソッドも含めました。

using System;
using System.Web;
using System.Data.SqlClient;
using Conf = System.Configuration.ConfigurationManager;
using System.Data;

public static class Sql {
    public static SqlConnection Connect() {
        // create & open connection
        SqlConnection result = new SqlConnection(Conf.ConnectionStrings["connectionString"].ConnectionString);
        result.Open();

        // add delegate to trigger when page has finished, to close the connection if it still exists
        System.Web.UI.Page page = HttpContext.Current.Handler as System.Web.UI.Page;
        if (page != null) {
            page.Unload += (EventHandler)delegate(object s, EventArgs e) {
                try {
                    result.Close();
                } catch (Exception) {
                } finally {
                    result = null;
                }
            };
        }

        // return connection
        return result;
    }

    public static SqlDataReader Exec(string name, params object[] parameters) {
        using (SqlCommand cmd = Connect().CreateCommand()) {
            cmd.CommandTimeout = int.Parse(Conf.AppSettings["commandTimeoutSec"]);
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = name;
            for (int x = 0; x + 1 < parameters.Length; x += 2) {
                SqlParameter p = cmd.Parameters.AddWithValue((string)parameters[x], parameters[x + 1]);
                if (parameters[x + 1] is string) {
                    p.DbType = DbType.AnsiString;
                }
            }
            return cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }
    }

    public static void Test() {
        using (SqlDataReader reader = Exec(
            "SELECT * FROM member WHERE name=@firstname AND age=YEAR(GETDATE())-@yearborn",
            "@firstname", "tom",
            "@yearborn", 1978)) {
            while (reader.Read()) {
                // read
            }
        }
    }
}
于 2010-05-24T18:41:54.380 に答える