The ObjectContext instance has been disposed and can no longer be used

7.3k views Asked by At

I've seen this question asked a million times, but every single suggestion I've encountered I already seem to have covered.

I have entity framework in my MVC solution, and I have a 'repository' which attempts to retrieve a collection of MyObjects:

public static List<MyObject> GetMyObjects()
{
   using (var context = new MyEntities())
   {
       return context.MyObjects.Include("Contact").OrderByDescending(o => o.Date).ToList();
   }
}

I call this method as part of a controller action which attempts to serialize it:

public JsonResult All()
{
   return Json(MyRepository.GetMyObjects(), JsonRequestBehavior.AllowGet);
}

And I get the following error:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

I don't know where to turn on this one, I appreciate entity framework 'lazy-loads' relational data sets if and when they're needed, and I appreciate attempting to serialize the whole collection would indeed attempt to load these (outside of the using statement), but I have the 'Include' there.

What I've Tried

I've tried the 'include', I've also ensured no other associations are part of the MyObject class (i.e. I have no other Include()s to write).

3

There are 3 answers

3
ocuenca On BEST ANSWER

To avoid this you have some options.Don't declare your navigation properties as virtual or disable Lazy Loading behavior on your context. Lazy loading is enable by default and is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook. So, if you want to work with a serializer I recommend you turn off lazy loading:

public class YourContext : DbContext 
{ 
    public YourContext() 
    { 
        this.Configuration.LazyLoadingEnabled = false; 
    } 
}

These links can help you to understand better what I explain in my answer:

If you remove the virtual keyword from your navigation properties, the POCO entity not meet the requirements described in the second link, so, EF won't create a proxy class to lazy load your navigation properties. But if you disabled lazy loading, even when your navigation properties are virtual, they won't be loaded in any entity. It's good idea disable lazy loading when you are using a serializer. Most serializers work by accessing each property on an instance of a type.

As a third option you could use the JsonIgnore attribute on your navigation properties that you don't want to be serialized as part of your entity, but as I said before, the best option is disable lazy loading.

2
Aram On

When you use Include and using Lazy loading, and wrap the dbContext in a Using statement, then once it tries to get the linked objects, the dbContext is already disposed. You can try eager loading of the navigation property like this:

IQueryable<MyObjects> query = db.MyObjects.Include(m => m.Contact);

Or you could take out the Using statement, as it is limiting your lazy loading...

0
Project Mayhem On

I had the same problem and solved like below;

I created a new object and put the values I am gonna use after getting object from db.

Example Code:

 var listFromDb= db.XTable.Where(x => x.Id > 5).ToList();

 var list = new List<Package>();

 foreach (var item in listFromDb)
 {
     var a = new Package()
     {
          AccountNo = item.AccountNo,
          CreateDate = item.CreateDate,
          IsResultCreated = item.IsResultCreated,
        };
        list.Add(a);
      }