我需要处理 MySqlCommand 吗?

3

我发现在每个查询中都写一个using语句(需要自己的命令或写parameters.clear())非常烦人,有时还需要在using块外声明变量。与未释放对象版本相比,这看起来非常烦人且不美观。

我需要释放它吗?如果我不这样做会发生什么?我知道当对象具有该接口时,释放对象是一种良好的实践。

3个回答

5

从Reflector中快速浏览,它似乎在其PreparableStatement上调用CloseStatement()方法,然后调用其超类(包括System.ComponentModel.Component)的Dispose()方法。 在整个调用链中的某个地方会调用NativeDriver.CloseStatement32(id),该方法会将一个命令写入连接流。

这不是我想要跳过的事情。 为什么要冒险呢?

这是你需要调整自己思考方式的时候之一。 你可能认为using看起来有些“不干净”,但就像闪耀着新油的齿轮系统一样,实际上它是清洁的标志。 你可以编写一个抽象来隐藏它,但你不应该摆脱它。


2
如果你的目标是ASP.NET,你可以设置Connect()方法(如果有的话)来在页面卸载时运行一个终结器。如果你遇到连接池耗尽的问题,这个技巧也非常好用。
我还包括了一个Exec方法,以简化使用类型安全参数编写SQL命令的过程 - 就像测试方法中的那样。
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
            }
        }
    }
}

0
如果你查看Connector/NET代码中的MySqlHelper.cs,你会发现MySqlCommands在那里没有被释放。
所以我猜在当前版本(8.0.33)中这并不是严格必要的,但这可能会在将来改变。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接