簡體   English   中英

我需要處理MySqlCommand嗎?

[英]Do i need to dispose of MySqlCommand?

我發現在我的每個查詢(需要自己的命令或寫參數.clear())上編寫一個using語句非常煩人,有時需要在using塊之外聲明變量。 與沒有處理物體的版本相比,它非常令人煩惱並且看起來更臟。

我需要處理它嗎? 如果我不這樣做會發生什么? 我知道在有對象時處理對象的好習慣。

從Reflector快速瀏覽一下,它似乎在其PreparableStatement上調用CloseStatement(),然后在其超類上調用Dispose(),包括System.ComponentModel.Component。 在鏈的某個地方,它最終調用NativeDriver.CloseStatement32(id),它將命令寫入連接流。

這不是我想要跳過的事情。 為何冒風險?

這是你需要調整自己思維的時候之一。 您可能會認為using看起來“臟”,但是 - 就像新鮮的油在齒輪系統上閃閃發光 - 它實際上是清潔的標志。 你可能能夠寫一個抽象來隱藏它,但你不應該擺脫它。

如果您的目標是ASP.NET,則可以設置Connect()方法(如果有的話)也設置終結器以在頁面卸載時運行。 如果您遇到連接池問題,這個技巧也很棒。

我還包括一個Exec方法來簡化用類型安全參數編寫SQL命令 - 就像在Test方法中一樣。

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
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM