【问题标题】:Automatically Open and Close Database Connection Within a Method在方法中自动打开和关闭数据库连接
【发布时间】:2014-07-11 13:40:23
【问题描述】:

我最近参与了一个现有项目,并试图减少重复代码的数量。

目前有很多与数据库交互相关的方法。数据库连接在这些方法中的每一个中打开和关闭。本质上,每个方法都使用完全相同的代码来打开和关闭连接。

    public static void AddToTable()
    { 
        DbConnection con = Common.CreateConnection();
        DbCommand cmd = con.CreateCommand();

        //cmd.CommandText = SQL COMMAND GOES HERE
        //cmd.ExecuteNonQuery();

        con.Close();
    }

我了解打开和关闭连接的重要性,但是在每种方法中看到这些完全相同的代码行我觉得很有趣。

C# 是否有某种方法可以在方法启动时自动创建连接(在本例中为 con 和 cmd 变量),然后在方法完成时关闭连接?

【问题讨论】:

  • 您正在寻找using 声明。
  • 看起来您还可以将数据库命令执行重构为另一种接受命令文本作为参数的方法。
  • @MichaelPetito 我想过,但是许多数据库命令都会有自定义参数,我觉得很快就会变得非常混乱。我帖子中的示例排除了这一点。

标签: c#


【解决方案1】:
public static void AddToTable()
{ 
    using( DbConnection con = Common.CreateConnection() ) 
    {
      DbCommand cmd = con.CreateCommand();

      //cmd.CommandText = SQL COMMAND GOES HERE
      //cmd.ExecuteNonQuery();
    }

}

因为 DBConnection 在 using 内部,并且 DbConnection 实现了接口 IDisposable,所以一旦超出范围,就会执行连接 .Dispose() 方法。

【讨论】:

    【解决方案2】:

    你可以这样做:

    using(var con = Common.CreateConnection())
    {
      using(var cmd = con.CreateCommand())
      {
          //cmd.CommandText = SQL COMMAND GOES HERE
          //cmd.ExecuteNonQuery();
      }
    }
    

    这将在关闭using 块后处理cmdcon 对象时自动关闭连接。它不会重构这些对象的创建,但老实说,无论如何都不应该重构。最好将这些对象完全保留在使用它们的方法的范围内。出于很好的理由重复代码并没有那么令人反感。 (事实上​​,有人可以说这甚至不是重复代码,因为它用于不同的业务目的。它只是重复击键。安迪在 IDE 中键入击键并不是软件开发的难点,维护其中的代码和抽象是。)

    【讨论】:

    • 命令通常不是必需的,除非您使用的是 OleDbCommand 或 OdBcCommand,但这是一个很好的做法。
    【解决方案3】:

    如果该方法正在执行数据库操作,那么您需要在同一方法本身中打开和关闭数据库连接,如果没有无限期打开连接的要求。 如果你使用 'Using' 语句,编译器会将代码转换为 try/finally 块。

    见下文,

    using (SqlConnection sqlConn = new SqlConnection("connectionstring"))
    {
          sqlConn.Open();
    
    }
    

    编译器将把这段代码转换成下面的样子。

    try
    {
         SqlConnection sqlConn = new SqlConnection("connectionstring");
         sqlConn.Open();
    
    }
    finally
    {
         sqlConn.Close();
    }
    

    【讨论】:

    • 它实际上会调用sqlConn.Dispose()
    【解决方案4】:

    除了using 块之外,还要考虑例如在实体框架中使用的工作单元模式。主要思想是将应用程序数据库工作的一些逻辑部分选择到一个单元中,并为每个单元打开和关闭一个连接。您的方法称为 AddToTable,因此我们可以假设使用一些具体的表数据,这些数据本身就是一组本质(此表中的行)。在这种情况下,一种可能的方法是将工作单元视为一组操作,在 CRUD 等表中具有单一本质。 DB连接的生命周期是:打开连接-CRUD单一本质-关闭连接。

    【讨论】:

      【解决方案5】:

      您可以创建辅助方法来将可重复的代码移入其中。类似的东西

      public static void WithDB(Action<SqlConnection, DbCommand> action)
      {
          using(var con = Common.CreateConnection())
          {
              var cmd = con.CreateCommand();
              action(con, cmd);
          }
      }
      

      这样使用

      public static void AddToTable()
      {
          WithDB((con, cmd)=>
          { 
              //cmd.CommandText = SQL COMMAND GOES HERE
              //cmd.ExecuteNonQuery();
          });
      
      }
      

      Proof.

      【讨论】:

        【解决方案6】:

        Lambda 是你的朋友....(实际上只是花时间重构了 400 多个 using 语句,因此只有一个地方创建了 sqlcommand(它是一个 using 语句)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-31
          • 2017-02-01
          • 1970-01-01
          • 2011-02-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多