Asp.net mvc 3 带有ef的asp.net mvc ObjectDisposedException
我需要一些帮助来解决此错误“ObjectContext实例已被释放,无法再用于需要连接的操作。” 它是一个asp.net mvc3、EF4和ms sql。 这是带有两个下拉菜单的剃须刀:Asp.net mvc 3 带有ef的asp.net mvc ObjectDisposedException,asp.net-mvc-3,Asp.net Mvc 3,我需要一些帮助来解决此错误“ObjectContext实例已被释放,无法再用于需要连接的操作。” 它是一个asp.net mvc3、EF4和ms sql。 这是带有两个下拉菜单的剃须刀: <div class="editRow"> @Html.DropDownListFor(m=>m.IndustryId, (SelectList)ViewBag.Industry, @Empower.Resource.General.ddlDefaultVal, new { @class =
<div class="editRow">
@Html.DropDownListFor(m=>m.IndustryId, (SelectList)ViewBag.Industry, @Empower.Resource.General.ddlDefaultVal, new { @class = "ddl400" })
@Html.ValidationMessageFor(m => m.IndustryId)
</div>
<div class="editRow">
@Html.DropDownListFor(m=>m.ProvinceId, (SelectList)ViewBag.Province, @Empower.Resource.General.ddlDefaultVal, new {@class = "ddl400"})
@Html.ValidationMessageFor(m => m.ProvinceId)
</div>
ProvinceService:
public IEnumerable<Province> GetAllProvince()
{
using (var context = DBContext.ObjectContext)
{
var pros = context.Provinces;
return pros;
}
}
我知道问题发生在第二个下拉列表中,当连接被前一个查询中断时,它尝试检索数据。请帮我解决这个问题,谢谢。修复程序很简单-使用前先转换为.ToList()或First()。LINQ已延迟执行,并在释放上下文后(当引用对象结果时)尝试运行此命令,而不是在实际进行调用时。。当上下文在范围内时,您需要强制它立即运行 using (var context = DBContext.ObjectContext) { var pros = context.Provinces; return pros.ToList(); }
总之是这样的:)我遇到了类似的问题。我一直遵循这种模式,我在web上的许多代码示例中都看到了这种模式:
public ActionResult Show(int id)
{
using (var db = new MyDbContext())
{
var thing = db.Things.Find(id);
return View(thing);
}
}
但是,每当我试图访问视图代码中未加载到内存中的任何内容(特别是主视图模型中的一对多关系)时,就会出现上面列出的ObjectDisposedException
我发现了一个不同的模式:
此模式使数据库连接保持活动状态,直到视图完成渲染,并在控制器本身被释放时整齐地将其释放。以下是使用时的问题
public class DBContext
{
private static EmpowerDBEntities _empowerContext;
public static EmpowerDBEntities ObjectContext
{
get
{
if (_empowerContext == null || _empowerContext.IsDisposed())
_empowerContext = new EmpowerDBEntities();
return _empowerContext;
}
}
}
using(var context=new CustomerContext())
{
return View(context.Customers.ToList());
}
当代码块执行时,所有的引用都被释放,这就是为什么它抛出这个错误的原因
所以我用
直接返回视图(context.Customers.ToList())它将工作得非常好。我按照您的建议使用了“return-pros.ToList();”,它抛出的对象就在这一行。非常感谢,我将尝试一下!但您能想出其他更好的方法来实现这一点吗?用查询数据库两次填充两个dropdownlists。我要做的一个小改动是在构造函数中将dbcontext传递给服务,在控制器中使用一个更大的using()块来包含它下面的所有代码,这样您就不会每次都实例化一个新上下文。这使您可以更轻松地模拟您的上下文,但您必须删除静态引用并使它们成为实例引用。您不能用任何模拟框架来模拟静态项,您必须用实例变量来包装它们。因此,只需让它们成为实例变量。或者-完全放弃将它们传递给构造函数,每个serviceservice类在需要时实例化自己的实例-这可能会更加独立,尽管如果您有任何事务,可能会导致运行时间较长的事务出现问题。
public ActionResult Show(int id)
{
using (var db = new MyDbContext())
{
var thing = db.Things.Find(id);
return View(thing);
}
}
public class MyController : Controller
{
private MyDbContext _db;
public MyController()
{
_db = new MyDbContext();
}
public ActionResult Show(int id)
{
// Do work such as...
var thing = _db.Things.Find(id);
return View(thing);
}
protected override void Dispose(bool disposing)
{
_db.Dispose();
base.Dispose(disposing);
}
}
using(var context=new CustomerContext())
{
return View(context.Customers.ToList());
}