Asp.net mvc 3 带有ef的asp.net mvc ObjectDisposedException

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 =

我需要一些帮助来解决此错误“ObjectContext实例已被释放,无法再用于需要连接的操作。”

它是一个asp.net mvc3、EF4和ms sql。 这是带有两个下拉菜单的剃须刀:

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