从数据库进行两次调用时出错

Error when doing two calls from DB

当我尝试使用相同的连接时出现错误 "Cannot acess to disposable object"。所以这是我的 Oracle 上下文:

public class MyOracleContext
{
    DbConnection connection;

    public MyOracleContext()
    {

        connection = new OracleConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
    }

    public TOut ExecuteCommand<TOut>(IDbCommand command, Func<IDataReader, TOut> mapHelper)
    {
        TOut result = default(TOut);
        try
        {
            using (connection)
            {
                using (command)
                {
                    if (connection.State != ConnectionState.Open)
                    {
                        connection.Open();
                    }
                    using (IDataReader reader = command.ExecuteReader(CommandBehavior.Default))
                    {
                        result = mapHelper(reader);
                    }
                }
            }
        }
        catch (Exception _exp)
        {
            throw new Exception("Error!" + _exp.Message);
        }
        return result;
    }

    public IDbCommand GetCommand()
    {
        OracleCommand cmd = (OracleCommand)connection.CreateCommand();
        cmd.BindByName = true;
        return cmd;
    }

    public IDataParameter GetParameter()
    {
        return new OracleParameter();
    }

    public bool ExecuteCommand(IDbCommand command)
    {
        bool result;
        try
        {
            using (connection)
            {
                command.Prepare();
                using (command)
                {
                    if (connection.State != ConnectionState.Open)
                    {
                        connection.Open();
                    }
                    result = command.ExecuteNonQuery() > 0;
                }
            }
        }
        catch (Exception _exp)
        {
            throw new Exception("Error!" + _exp.Message);
        }
        return result;
    }

    public DbParameter GetParameter(string name, object value)
    {
        OracleParameter para = new OracleParameter(name, value);
        para.Size = int.MaxValue;
        return para;
    }
}

我使用 ExecuteCommand 从数据库中获取结果,并使用 ExecuteCommand 来插入,例如。但是,当我在同一个方法上使用这两个命令时,它给我错误 "Cannot access to disposable object",当我在方法 上执行 Connection.Open 时]执行命令。但是,如果我执行相反的顺序(首先使用 ExecuteCommand,然后使用 ExecuteCommand),它就会通过。问题是我想从 BD 中获取结果,进行比较然后插入。知道为什么吗?我已经被困在这里好几个小时了

将 "return result;" 更改为 using(){ }

像那样:

public TOut ExecuteCommand<TOut>(IDbCommand command, Func<IDataReader, TOut> mapHelper)
{
    TOut result = default(TOut);
    try
    {
        using (connection)
        {
            using (command)
            {
                if (connection.State != ConnectionState.Open)
                {
                    connection.Open();
                }
                using (IDataReader reader = command.ExecuteReader(CommandBehavior.Default))
                {
                   return result = mapHelper(reader);
                }
            }
        }
    }
    catch (Exception _exp)
    {
        throw new Exception("Error!" + _exp.Message);
    }

}

您持有 DbConnection 作为 class 的 属性,但在执行命令后处理它。如果随后使用同一实例执行另一个命令,则它正在尝试使用已释放的连接。

连接由 .NET 汇集,因此创建起来相对便宜。我只想在 ExceuteCommand 方法中创建命令:

public TOut ExecuteCommand<TOut>(IDbCommand command, Func<IDataReader, TOut> mapHelper)
{
    TOut result = default(TOut);
    //try
    //{
        using (DbConnection connection = new OracleConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
        {
            //using (command)
            //{
                if (connection.State != ConnectionState.Open)
                {
                    connection.Open();
                }
                using (IDataReader reader = command.ExecuteReader(CommandBehavior.Default))
                {
                    result = mapHelper(reader);
                }
            //}
        }
    }
    //catch (Exception _exp)
    //{
    //    throw new Exception("Error!" + _exp.Message);
    //}
    return result;
}

我建议进行另外两项更改:

  • 您不应在此方法中处理 命令 ,因为它并未创建它。负责创建一次性物品的是 负责处理它。
  • 不要捕获任何异常,只是为了抛出另一个普通的 Exception,仅提取错误消息。要么只是让异常冒泡,要么做一些有意义的事情(记录它,添加更多上下文等),然后抛出一个新的异常附加原始异常作为InnerException或者重新抛出异常