【问题标题】:Database Connection from another class来自另一个类的数据库连接
【发布时间】:2017-02-01 20:00:19
【问题描述】:

我在我的程序中创建了一个类来处理数据库连接。该类包括一个名为OpenConnection() 的方法,用于打开与数据库的连接。我不相信我的程序符合干净代码的标准。方法如下。

public void OpenConnection()
{
  if(connection==null || connection.State != Connection.Open)
  {
     connection = new OracleConnection(this.connectionString);
     connection.Open();
  }
}

这种方法可以正常工作,但我只是想确定这是否是一种安全的方法,并且我没有以任何方式利用我的程序。提前谢谢你

更新

我还在类中添加了以下方法来关闭连接并释放它。

    public void CloseConnection()
    {
        if (dbconnect != null | dbconnect.State != ConnectionState.Closed)
        {
            dbconnect.Close();
        }
    }

    //Here the IDsiposable method is implemented
    public void Dispose()
    {
        CloseConnection();
    }

【问题讨论】:

  • @Igor 我已经用我在课堂上声明的剩余方法更新了我的问题。现在可以看看它并告诉我这是否可以。我是用dispose方法关闭SqlConnection(OracleConnection)实例吧?
  • @Igor 你能建议我改进一下吗?谢谢
  • @Igor 我不明白你在第三条评论中的解决方案。

标签: c# sql oracle


【解决方案1】:

你可以使用 using 子句,它会自动处理 Dispose。

using (SqlConnection connection = new SqlConnection(connectionString))
    {

    connection.Open();
    SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.Add(new SqlParameter("@EmployeeID", 123));
    command.CommandTimeout = 5;

    command.ExecuteNonQuery();

    connection.close();
}

【讨论】:

    【解决方案2】:

    如果您添加this answer 中建议的案例并且如果它打算在单个线程上使用并且在非常有限的范围内,您的编码解决方案似乎没问题。也就是说,您似乎正准备在许多方法调用中使用此类作为参数,因为您想要

    • 混合业务逻辑和持久性问题
    • 或以其他方法不必关心是否打开连接的方式共享实例(例如调用堆栈中的更高调用尚未调用Open)或不(例如先前的在调用堆栈中调用是否打开了连接(我们称之为“环境”连接)。

    这些策略中的任何一个通常都会导致麻烦。最好将范围保持在较小的范围内,以便您知道连接已打开以及何时关闭:

    using (var connection = new OracleConnection(...))
    {
        connection.Open();
        ...
    }
    

    当你有这么小的范围时,你的抽象现在没有任何价值。

    【讨论】:

      【解决方案3】:

      由于 OracleConnection 实现了 IDisposable,您可能存在资源泄漏。此外,在 ConnectionState.Executing 或 Fetching 中对连接调用 close 可能很糟糕,因为它会回滚所有未提交的事务。

      public void OpenConnection()
      {
        if (connection == null)
        {
           connection = new OracleConnection(this.connectionString);
           connection.Open();
           return;
        }
      
        switch (connection.State)
        {
           case ConnectionState.Closed:
           case ConnectionState.Broken:
             connection.Close();
             connection.Dispose();
             connection = new OracleConnection(this.connectionString);
             connection.Open();
             return;
        }
      }
      

      【讨论】:

      • 所以不需要CloseConnection()Dispose() 方法?
      • 您在我的回答之后添加了这些;)您可能希望阻止关闭处于执行状态的连接,但我个人从来不需要。
      猜你喜欢
      • 2019-11-01
      • 1970-01-01
      • 2019-01-02
      • 2013-08-22
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多