asp.net mvc ObjectDisposedException with ef

时间:2011-07-27 05:02:23

标签: 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 = "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>

控制器:

 IndustryService indService = new IndustryService();
ViewBag.Industry = new SelectList(indService.GetAllIndustry(), "IndustryId", "IndustryName");
ProvinceService proService = new ProvinceService();
ViewBag.Province = new SelectList(proService.GetAllProvince(), "ProvinceId", "ProvinceName");
 return View();

ProvinceService:

public IEnumerable<Province> GetAllProvince()
        {
            using (var context = DBContext.ObjectContext)
            {
                var pros = context.Provinces;
                return pros;
            }
        }

IndustryService与上述相同......

public class DBContext
    {
        private static EmpowerDBEntities _empowerContext;
        public static EmpowerDBEntities ObjectContext
        {
            get
            {
                if (_empowerContext == null)
                    _empowerContext = new EmpowerDBEntities();
                return _empowerContext;
            }
        }
    }

我知道当第二次下拉列表中的问题发生时,它尝试在先前查询关闭连接时检索数据。请帮助我,谢谢。

3 个答案:

答案 0 :(得分:6)

修复很简单 - 在使用之前转换为.ToList()或First()。 LINQ延迟执行并尝试在处理上下文后(当引用对象结果时)运行此命令 - 而不是在您实际进行调用时...您需要强制它立即运行 背景是在范围内。

using (var context = DBContext.ObjectContext)
{
     var pros = context.Provinces;
     return pros.ToList();
}

另外 - 上面的代码是在get访问器中检查null。但是这个对象不会为空 - 它会被丢弃,所以你不能这样检查,你需要检查它是否为null而不是处理。


public class DBContext
    {
        private static EmpowerDBEntities _empowerContext;
        public static EmpowerDBEntities ObjectContext
        {
            get
            {
                if (_empowerContext == null || _empowerContext.IsDisposed())
                    _empowerContext = new EmpowerDBEntities();
                return _empowerContext;
            }
        }
    }

总之这样的事情:)

答案 1 :(得分:0)

我遇到了类似的问题。我一直在关注这种模式,我在网上的许多代码示例中都看到了这种模式:

public ActionResult Show(int id)
{
   using (var db = new MyDbContext())
   {
      var thing = db.Things.Find(id);
      return View(thing);
   }
}

但是,每当我尝试访问未在View代码中加载到内存中的任何内容时(特别是主视图模型中的一对多关系),这就会导致上面列出的ObjectDisposedException。 / p>

我在this example中找到了不同的模式:

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

此模式使数据库连接保持活动状态,直到View完成呈现,并在Controller本身处理时整齐地处理它。

答案 2 :(得分:0)

使用

时出现问题
using(var context=new CustomerContext())
{

     return View(context.Customers.ToList());
}

当代码块执行时,所有引用都被处理掉,因为你加载了这个错误。

所以我用了

直接返回View(context.Customers.ToList())它将完美地运行。