从DB执行两次调用时出错

时间:2015-03-06 12:40:36

标签: c# asp.net-mvc oracle asp.net-mvc-3

当我尝试使用相同的连接时,我收到错误“无法访问一次性对象”。所以这是我的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 从DB获取结果,并使用ExecuteCommand获取,例如,插入。但是,当我在同一个方法上使用这两个命令时,它给出了错误“无法访问一次性对象”,当我执行Connection.Open时,对方法 ExecuteCommand 。但是,如果我执行逆序(首先使用ExecuteCommand然后使用ExecuteCommand),它会通过。问题是我想从BD获得结果,进行比较然后插入。知道为什么吗?我被困在这里好几个小时

2 个答案:

答案 0 :(得分:0)

更改&#34;返回结果;&#34;到使用(){}

里面

就像那样:

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);
    }

}

答案 1 :(得分:0)

您持有DbConnection作为类的属性,但在执行命令后将其丢弃。如果然后使用相同的实例执行另一个命令,则它尝试使用已布置的连接。

.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或重新抛出例外