开发者

asp.net mvc ObjectDisposedException with ef

I need some help with this error "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."

It's a asp.net mvc3, EF4, and ms sql. Here is the razor with two dropdowns:

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

Controller:

 IndustryService indService = new IndustryService();
ViewBag.Industry = new SelectList(indService.GetA开发者_如何学编程llIndustry(), "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 is identical as above...

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

I know the problem occurs in second dropdown when it tries to retrive data while the connection is desposed by previous query. Please help me with this, thanks.


The fix is simple - convert to a .ToList() or First() before using. LINQ has deferred execution and tries to run this command after the context is disposed (when your object results are referenced) - not when you actually make the call.. You need to force it to run now while the context is in scope.

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

Also - your code above is checking for null in the get accessor. However this object won't be null - it will be disposed, so you cannot do your check this way, you need to check if its null and not disposed.


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

something like that anyways :)


I ran into a similar problem. I had been following this pattern, which I had seen in many code examples on the web:

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

However, this was causing the ObjectDisposedException listed above whenever I tried to access anything that hadn't been loaded into memory in the View code (in particular, one-to-many relationships in the main view model).

I found a different pattern in 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);
   }
}

This pattern keeps the database connection alive until the View has finished rendering, and neatly disposes of it when the Controller itself is disposed.


Here is the problem when you are using

using(var context=new CustomerContext())
{

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

when the block of code executes all references are disposed that you are lazzy loading so that's why it is throwing this error.

so i used

return View(context.Customers.ToList()) directly it will work perfectly fine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜