从数据库进行两次调用时出错
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
或者重新抛出异常
当我尝试使用相同的连接时出现错误 "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
或者重新抛出异常