这看起来似乎微不足道,但它真的很困扰我.我今天开始在MVC项目中使用Dapper并创建了一个非常简单的POCO对象; 当我运行这个项目时,我收到以下错误消息:
无法访问已处置的对象
对象名称:'OracleConnection'.
这是代码:
public class MyController : Controller
{
readonly IDbConnection sqlConn = new OracleConnection(ConfigurationManager.ConnectionStrings["LogDbContext"].ConnectionString);
readonly string selectLog = "select * from LOG";
readonly string insertLog = "insert into LOG (ID, Address) values (:ID, :Address)";
// GET: Log
public ActionResult Index()
{
using (sqlConn)
{
sqlConn.Open();
//IEnumerable log = sqlConn.Query(selectLog);
IEnumerable<Log> log = sqlConn.Query<Log>(selectLog);
foreach (var item in log)
{
Console.WriteLine(item.ToString());
}
}
return View();
}
public ActionResult Create()
{
using (sqlConn)
{
sqlConn.Open();
var log = new Log()
{
ID = 1,
Address = "test"
};
sqlConn.Execute(insertLog, log);
}
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
似乎将"sqlConn"放入using语句会使其自动处理,因此当函数再次运行时,它无法在连接上运行.
我怎么能阻止这个?我不希望每次需要时都手动打开和关闭连接.
UPDATE
使用下面答案提供的所有帮助(一切正确)我最后使用类的构造函数在每次必须使用类时实例化一个新连接.
//removed the wrong static attribute and the instantiation
readonly IDbConnection sqlConn;
readonly string selectLog = "select * from LOG";
readonly string insertLog = "insert into LOG (ID, Address) values (:ID, :Address)";
// Created a constructor to instantiate the connection everytime the controller gets called
public LogController()
{
sqlConn = new OracleConnection(ConfigurationManager.ConnectionStrings["LogDbContext"].ConnectionString);
}
Run Code Online (Sandbox Code Playgroud)
似乎将"sqlConn"放入using语句会使其自动处理
是的,这就是using声明的用途.
我怎么能阻止这个?我不希望每次需要时都手动打开和关闭连接.
我强烈建议你做开放,每次你需要它的时候关闭连接-但使用它的局部变量,而不是一个领域.这样每个操作都会获得一个单独的逻辑连接,因此您不必担心线程问题等.让连接池负责提高效率.我怀疑你担心在每次调用时打开一个"物理"连接(建立一个新的TCP/IP连接或其他) - 但连接池是为了确保不会发生这种情况超出需要.
只需在方法中创建一个新连接:
using (var connection = new OracleConnection(...))
{
...
}
Run Code Online (Sandbox Code Playgroud)
...并测量性能以确定它是否令人满意.不要开始猜测你是否会遇到问题(并采用导致比他们解决的更多问题的不良解决方法).
作为使用的替代方法new,控制器构造函数可以接受连接提供程序并要求新连接,但从根本上说它是关于每次创建新的一次性连接.
如果由于某种原因你真的,真的不想处理连接,只需删除using语句 - 但要非常清楚你需要自己处理并发.你几乎肯定不想那样做.
您声明了sqlConnas static readonly,这意味着整个应用程序只有一个实例.将其包装using()意味着在第一个请求完成后,处理sqlConn被丢弃并且后续请求失败ObjectDisposedException.
要解决此问题,请按如下方式重写代码:
var connectionString =
ConfigurationManager.ConnectionStrings["LogDbContext"].ConnectionString;
using(var sqlConn = new OracleConnection(connectionString))
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在,至于你不想每次都打开连接,这就是你必须要做的.连接很珍贵,必须小心管理:尽可能晚开,一旦你不再需要就关闭.您始终可以将连接初始化逻辑分解为单独的方法,或者采用Enterprise(r)(tm)方式并将其注入.
| 归档时间: |
|
| 查看次数: |
534 次 |
| 最近记录: |