【问题标题】:OracleDataReader. Error: Invalid operation. The connection is closed甲骨文数据阅读器。错误:无效操作。连接已关闭
【发布时间】:2014-03-31 03:24:27
【问题描述】:

从 Oracle DB 获取内容时遇到错误。

这是我的代码:

public virtual IDataReader LoadDataReaderWithSqlString(string strQuery, ISessionScope session)
    {
        var s = GetSession(session);
        using (var connection = s.Connection)
        {
            var command = connection.CreateCommand();
            command.Connection = connection;
            if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken)
                connection.Open();
            command.CommandType = CommandType.Text;
            command.CommandText = s.CreateSQLQuery(strQuery).ToString();
            s.Transaction.Enlist(command); // Set the command to exeute using the NHibernate's transaction
            using (var dataReader = command.ExecuteReader())
            {
                if(dataReader.Read())
                    return dataReader;
            }
        }
        return null;
    }

当我调试时,我能够在 dataReader 中看到返回值。 我使用 NHibernate 运行原始 SQL。我想返回 DataReader。谁能帮帮我?

【问题讨论】:

    标签: c# datareader


    【解决方案1】:

    您是否要返回打开的IDataReader?问题是您将ExecuteReader 包装在using 语句中。 using 表示您的dataReader 将在using 内部的代码执行后被释放。所以你返回处置的对象。解决办法是:去掉using:

    var dataReader = command.ExecuteReader();
    if(dataReader.Read())
        return dataReader;
    

    连接对象也是如此。

    添加

    正如大卫在 cmets 中提到的,您可能希望避免资源泄漏(我的意思是打开连接但未执行命令的情况),那么您应该像这样处理异常:

    public virtual IDataReader LoadDataReaderWithSqlString(string strQuery, ISessionScope session)
    {
        try 
        {
            var s = GetSession(session);
            var connection = s.Connection;
    
            var command = connection.CreateCommand();
            command.Connection = connection;
            if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken)
                connection.Open();
    
            command.CommandType = CommandType.Text;
            command.CommandText = s.CreateSQLQuery(strQuery).ToString();
            s.Transaction.Enlist(command); // Set the command to exeute using the NHibernate's transaction
    
            try
            {
                var dataReader = command.ExecuteReader();
                if(dataReader.Read())
                    return dataReader;
            }
            catch (DbException)
            { 
                // error executing command
                connection.Close();
                return null; // or throw; // it depends on your logic
            }
        }
        catch (DbException)
        {
            // if connection was not opened
            return null; // or throw; // it depends on your logic
        }
        return null;
    }
    

    【讨论】:

    • 也许将所有内容都包装在一个 try catch 中?
    • @DavidMerinos 是的,这可能是一个选择。谢谢!
    • 这里的第二行可能是多余的: var command = connection.CreateCommand(); command.Connection = 连接;
    • 嗯。我仍然得到错误。无效操作。 OracleDataReader 已关闭。
    • @kingjia 好的,我需要更多细节:你为什么不创建一个新的DbConnection 而不是使用一些现有的?这可能会给您带来问题。
    【解决方案2】:

    那是因为你有

    using (var connection = s.Connection)using (var dataReader = command.ExecuteReader())

    using 块将处理对象(此处为 connectiondataReader

    如果您需要返回dataReader,请删除 using 块

    【讨论】:

      猜你喜欢
      • 2013-06-08
      • 1970-01-01
      • 1970-01-01
      • 2017-06-12
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多