Entity Framework: error The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

Standard

“The ObjectContext instance has been disposed and can no longer be used for operations that require a connection”: this error is quite common for all those operation which involves entities containing navigational properties/graph data/related data

2016-02-18 07_23_25-MyHomepage (Debugging) - Microsoft Visual Studio

In the above case, I was updating Course entity while Technology entity was navigational property in Course. As you can see all properties of Course have been pulled from database except of Technology data. Just go through code below:

Snapshot of Context class code:

 

2016-02-18 07_28_46-MyHomepage - Microsoft Visual Studio

Repository Class code:

        public T GetByID(int key)
        {
            using (var context = new PluralSightContext())
            {
                T existing = context.Set<T>().Find(key);
                return existing;
            }
        }
 
        public virtual T Update(T obj, int key)
        {
            using (var context = new PluralSightContext())
            {
                if (obj == null)
                    return null;
 
                T existing = GetByID(key);
                if (existing != null)
                {
                    context.Entry(existing).CurrentValues.SetValues(obj);
                    context.SaveChanges();
                }
                return existing;
            }
        }

Solution 1 (least appropriate):

Since lazy loading is activated as you can see from context class constructor code, By default Entity Framework uses lazy-loading for navigation properties. That’s why these properties should be marked as virtual – EF creates proxy class for your entity and overrides navigation properties to allow lazy-loading, so in order to resolve your problem either use eager loading (.include(), .attach()) or explicit loading(.load()) and remove Virtual keyword from navigational properties. But I wont recommend this technique because it has performance impact, it will start loading all graph data for all entities, in order to make it happen only for single entity you have to write extra line of codes in context class.

MSDN Reference Link on Loading Strategies

Solution 2:

As you can see from above code we are creating two context first for GetByID function and the for Update function, I have using block around existing usage. Which disposes context before entities are returned. When some code later tries to use lazy-loaded navigation property, it fails, because context is disposed at that moment.

I am ending your context prematurely: a DbContext should be available throughout the unit of work being performed, only disposing it when you’re done with the work at hand. In the case of ASP.NET, a unit of work is typically the HTTP request being handled.

So if we move GetByID logic under one using statement, so this will resolve above issue:

        public virtual T Update(T obj, int key)
        {
            using (var context = new PluralSightContext())
            {
                if (obj == null)
                    return null;
 
                T existing = context.Set<T>().Find(key);
                if (existing != null)
                {
                    context.Entry(existing).CurrentValues.SetValues(obj);
                    context.SaveChanges();
                }
                return existing;
            }
        }
Advertisements

3 thoughts on “Entity Framework: error The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s