2011-07-27 62 views
3

我需要一些帮助,这个错误“的ObjectContext实例已被处置,不能再用于需要连接的操作。”asp.net mvc ObjectDisposedException与ef

这是一个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; 
      } 
     } 
    } 

我知道第二次下拉时,如果尝试在前一个查询拒绝连接时尝试检索数据,则会出现问题。请帮助我,谢谢。

回答

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

类似的东西反正:)

+0

我做了你的建议,使用“返回优点。tolist();“,它抛出的对象正好放置在这一行 – Jack

+0

看到我的编辑你有另外一个问题,我上面解决 –

+0

非常感谢你,我会尝试!但你能想到其他更好的方式来实现这个 - 用两次查询数据库填充两个下拉列表 – Jack

0

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

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

然而,这是造成上述每当我试图访问尚未被加载到内存中的任何上市的ObjectDisposedException视图代码(特别是主视图模型中的一对多关系)。

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

这种模式会使数据库连接的生命,直到查看已经完成的渲染,整齐控制器本身配置时其配置。

0

下面是当您使用

using(var context=new CustomerContext()) 
{ 

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

时的代码块执行的所有引用设置你是lazzy装载所以这就是为什么它被抛出该错误的问题。

所以我用

返回查看(context.Customers.ToList())直接将它完全正常工作。