Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从数据库进行两次调用时出错_C#_Asp.net Mvc_Oracle_Asp.net Mvc 3 - Fatal编程技术网

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

C# 从数据库进行两次调用时出错,c#,asp.net-mvc,oracle,asp.net-mvc-3,C#,Asp.net Mvc,Oracle,Asp.net Mvc 3,当我尝试使用相同的连接时,出现错误“无法访问一次性对象”。这就是我的Oracle上下文: public class MyOracleContext { DbConnection connection; public MyOracleContext() { connection = new OracleConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].Connec

当我尝试使用相同的连接时,出现错误“无法访问一次性对象”。这就是我的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;
    }
}
公共类MyOracleContext
{
数据库连接;
公共MyOracleContext()
{
连接=新的OracleConnection(ConfigurationManager.ConnectionString[“DefaultConnection”].ConnectionString);
}
public TOut ExecuteCommand(IDbCommand,Func mapHelper)
{
TOut结果=默认值(TOut);
尝试
{
使用(连接)
{
使用(命令)
{
if(connection.State!=ConnectionState.Open)
{
connection.Open();
}
使用(IDataReader reader=command.ExecuteReader(CommandBehavior.Default))
{
结果=mapHelper(读卡器);
}
}
}
}
捕获(例外情况)
{
抛出新异常(“错误!”+\u exp.Message);
}
返回结果;
}
公共IDbCommand GetCommand()
{
OracleCommand cmd=(OracleCommand)connection.CreateCommand();
cmd.BindByName=true;
返回cmd;
}
公共IDataParameter GetParameter()
{
返回新的OracleParameter();
}
public bool ExecuteCommand(IDbCommand)
{
布尔结果;
尝试
{
使用(连接)
{
command.Prepare();
使用(命令)
{
if(connection.State!=ConnectionState.Open)
{
connection.Open();
}
结果=command.ExecuteOnQuery()>0;
}
}
}
捕获(例外情况)
{
抛出新异常(“错误!”+\u exp.Message);
}
返回结果;
}
公共DbParameter GetParameter(字符串名称、对象值)
{
OracleParameter para=新的OracleParameter(名称、值);
参数大小=int.MaxValue;
返回段;
}
}
我使用ExecuteCommand从DB中获取结果,并使用ExecuteCommand,例如,Insert。但是,当我在同一方法上使用这两个命令时,当我进行连接时,会出现错误“无法访问一次性对象”。但是如果我按照相反的顺序(先使用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);
    }

}
public TOut ExecuteCommand(IDbCommand,Func-mapHelper)
{
TOut结果=默认值(TOut);
尝试
{
使用(连接)
{
使用(命令)
{
if(connection.State!=ConnectionState.Open)
{
connection.Open();
}
使用(IDataReader reader=command.ExecuteReader(CommandBehavior.Default))
{
返回结果=mapHelper(读卡器);
}
}
}
}
捕获(例外情况)
{
抛出新异常(“错误!”+\u exp.Message);
}
}

您将
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;
}
public TOut ExecuteCommand(IDbCommand,Func-mapHelper)
{
TOut结果=默认值(TOut);
//试一试
//{
使用(DbConnection connection=new OracleConnection(ConfigurationManager.ConnectionString[“DefaultConnection”].ConnectionString))
{
//使用(命令)
//{
if(connection.State!=ConnectionState.Open)
{
connection.Open();
}
使用(IDataReader reader=command.ExecuteReader(CommandBehavior.Default))
{
结果=mapHelper(读卡器);
}
//}
}
}
//捕获(例外情况)
//{
//抛出新异常(“错误!”+\u exp.Message);
//}
返回结果;
}
我还建议进行另外两项修改:

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

为什么不创建新连接?请参阅此链接:Stanley,感谢您的详细解释。按照您的说明进行操作,但现在我在使用(IDataReader=command.ExecuteReader(CommandBehavior.Default))时遇到错误“连接必须打开”。为什么?我在打开连接之前!您需要将该命令与您创建的连接相关联:
command.connection=connection
。这些类型的东西通常是命令和连接没有像这样抽象的原因-有足够的耦合,通常可以更干净地将它们管理在一起,即使这意味着一些代码重复。