3

我想为更多查询重用一个 OracleConnection 对象,所以我写了一个简单的类:

public static class DbConnectionsManager
    {
        /// <summary>
        /// 
        /// </summary>
        private static OracleConnection _dbConnection = null;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="aConnectionString"></param>
        /// <returns></returns>
        public static OracleConnection GetDatabaseConnection(string aConnectionString) 
        {
            try
            {
                if (_dbConnection == null)
                {
                    _dbConnection = new OracleConnection(aConnectionString);
                    _dbConnection.Open();
                    return _dbConnection;
                }

                if (_dbConnection.State == System.Data.ConnectionState.Closed)
                {
                    _dbConnection.ConnectionString = aConnectionString;
                    _dbConnection.Open();
                    return _dbConnection;
                }

                if (!_dbConnection.ConnectionString.Equals(aConnectionString))
                {
                    _dbConnection.Close();
                    _dbConnection.ConnectionString = aConnectionString;
                    _dbConnection.Open();
                    return _dbConnection;
                }

                return null;
            }
            catch (Exception e)
            {

                return null;
            }
        }
    }

这样我可以多次使用连接:

  using (OracleConnection connection = 
           DbConnectionsManager.GetDatabaseConnection(aDbConnectionString))
            {
                OracleCommand command = connection.CreateCommand();
                string sql = "SELECT * FROM MYTABLE";
                command.CommandText = sql;

                OracleDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    string myField = (string)reader["EXAMPLE"];
                    Console.WriteLine(myField);
                }
            }

当我第一次调用该方法时,一切正常。如果我记得静态对象是 != null 但连接结果关闭的方法!我从不关闭连接!

当您尝试重新打开连接时,我有此异常

....
if (_dbConnection.State == System.Data.ConnectionState.Closed)
                {
                    _dbConnection.ConnectionString = aConnectionString;
                    _dbConnection.Open();
                    return _dbConnection;
                }
...

错误

Message = "Cannot access a disposed object.\r\nObject name: 'OracleConnection'."
4

3 回答 3

6

正如错误所说,它是一个已处置的对象。这意味着您需要删除该using (子句;这个子句处理了你的连接对象,这就是为什么你不能在外面使用这个对象using (。这意味着如果你想在外面使用它,你需要创建一个新的类对象using (

请参阅: C# Using 语句

于 2013-04-18T08:13:01.583 回答
1

正如另一个答案所解释的那样,该using子句并不适合您想要重用的东西。但是我有同样的想法 - 我仍然想使用这种类型的模式来自动打开和自动关闭连接。如果这是您希望做的,那么关键是您“使用”的对象不能是 OracleConnection 本身,因为您确实想重用它,并且“使用”它会杀死它。你真的只想要一个新对象,它在创建时打开连接,在 Dispose 时关闭连接,仅此而已。这应该可以解决问题(我将它用于我自己的目的):

internal class OpenedContext : IDisposable
{
    private OracleConnection _connection;

    public OpenedContext(OracleConnection conn) {
        _connection = conn;
        if (_connection.State != System.Data.ConnectionState.Open) _connection.Open();            
    }

    public void Dispose() {
        if (_connection.State != System.Data.ConnectionState.Closed) _connection.Close();
    }

}

然后在您的示例中,您可以执行类似...

            // Early on...
            OracleConnection _connection = DbConnectionsManager.GetDatabaseConnection(aDbConnectionString);

            // ... Later on, in various other calls ...
            using (new OpenedContext(_connection))
            {
                OracleCommand command = _connection.CreateCommand();
                string sql = "SELECT * FROM MYTABLE";
                command.CommandText = sql;
                OracleDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    string myField = (string)reader["EXAMPLE"];
                    Console.WriteLine(myField);
                }
            }

虽然它在某种程度上很愚蠢,但我绝对更喜欢设置这样的模式,而不是总是期望未来的编码人员在每个数据库调用周围手动“包装”重新打开和重新关闭。它更具可读性(或可忽略)且风险较小(如果您非常担心在空闲时关闭连接)。

于 2015-06-23T19:44:59.480 回答
0
public OracleConnection GetConnection()
{

//Romove using(...) clouse 
using (OracleConnection conn = new OracleConnection(_connSettings.GetConnectionString()))
{return con;}

问题是内部 using() 子句问题。

using (OracleConnection con = GetConnection()){}
于 2019-01-22T12:13:31.550 回答