【问题标题】:Do i need to dispose of MySqlCommand?我需要处理 MySqlCommand 吗?
【发布时间】:2011-02-23 08:33:32
【问题描述】:

我发现在我的每个查询(需要自己的命令或编写 parameters.clear())上编写 using 语句非常烦人,这有时需要在 using 块之外声明变量。与没有处理对象的版本相比,它非常烦人并且看起来更脏。

我需要处理它吗?如果我不这样做会怎样?我确实知道在具有该接口时处置对象的良好做法。

【问题讨论】:

    标签: .net mysql sqlcommand


    【解决方案1】:

    快速浏览一下 Reflector,它似乎在其 PreparableStatement 上调用 CloseStatement(),然后在其超类上调用 Dispose(),包括 System.ComponentModel.Component。在链的某处,它最终调用 NativeDriver.CloseStatement32(id),它将命令写入连接流。

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

    这是您需要调整自己的想法的时候之一。你可能会认为using 看起来很“脏”,但是——就像齿轮系统上闪闪发光的新鲜油一样——它实际上是清洁的标志。你也许可以写一个抽象来隐藏它,但你不应该摆脱它。

    【讨论】:

      【解决方案2】:

      如果你的目标是 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
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-02
        • 2010-10-15
        • 2021-08-11
        • 2015-11-09
        • 2019-09-05
        相关资源
        最近更新 更多