I am using EF 4 to retrieve a list of Employees.
public ContentResult AutoCompleteResult(string searchText)
{
List<Employee> list = Employee.GetAllCurrentEmployees();
List<Employee> filteredEmployees = list
.Where(x => x.GetName().ToLower().Contains(searchText.ToLower()))
.ToList();
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
var jsonString = jsonSerializer.Serialize(filteredEmployees).ToString();
return Content(jsonString);
}
The list is retrieved OK, but when I serialize it, I get this exception;
System.ObjectDisposedException: The ObjectContext instance has been
disposed and can no longer be used for
operations that require a connection.
Generated: Wed, 17 Nov 2010 16:06:56 GMT
System.ObjectDisposedException: The ObjectContext instance has been
disposed and can no longer be used for operations that require a connection.
at
System.Data.Objects.ObjectContext.EnsureConnection()
at
System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) at
System.Data.Objects.ObjectQuery`1.Execute(MergeOption mergeOption) at
System.Data.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption) at
System.Data.Objects.DataClasses.EntityCollection`1.Load(MergeOption mergeOption) at
System.Data.Objects.DataClasses.RelatedEnd.Load() at
System.Data.Objects.DataClasses.RelatedEnd.DeferredLoad() at
System.Data.Objects.DataClasses.EntityCollection`1.System.Collections.IEnumerable.GetEnumerator() at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat
serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat
serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat
serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object
o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat
serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse,
SerializationFormat
serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat
serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object
o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat
serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object
obj, StringBuilder output, SerializationFormat serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object
obj, SerializationFormat serializationFormat) at
System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) at
SHP.Controllers.EmployeeController.AutoCompleteResult(String searchText) in C:\Documents and Settings\geoffreypayne\My Documents\Visual Studio
2010\Projects\MVC\SHP\SHP\Controllers\EmployeeController.cs:line
623 at lambda_method(Closure , ControllerBase , Object[] ) at
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext
controllerContext, IDictionary`2 parameters) at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at
System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.InvokeActionMethodWithFilters>b__a()
at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
filter, ActionExecutingContext preContext, Func`1 continuation)
at
System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<>c__DisplayClassf.<InvokeActionMethodWithFilters>b__c() at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) at
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext
controllerContext, String actionName)
I find this very odd. I have already retrieved the list of employees and the DataContext has been disposed. So why would I get this error?
It sounds like you have some lazily loaded relationship properties that have not yet loaded (which has an associated "n+1" performance concern). You can try eager loading to see if this helps; otherwise, explicitly load the data for each item in the list, before you close the object-context.
You could turn off lazy loading to resolve this problem.
Inside your 'using' block, try this:
yourObjectContext.ContextOptions.LazyLoadingEnabled = false;
After doing this, I was able to serialize my EF (DbContext-generated) POCO to JSON without any issue.
*Note: Since I've turned off lazy loading... I explicitly pull in related objects I need ahead of time (mostly with .Include() in my query) before the object is serialized to JSON.
Thought I would chime in here with my 2 cents. We had a very big data access layer, and one of the programmers was used to using a using statement for the context like so:
using (EntityModel myContext = EntityConnection)
{
//code in here to grab data
}
We are using the EntityConnection as a static property that serves up a dbContext per current HttpContext. Any method called after his using block would throw the exception 'ObjectContext instance has been disposed' since obviously the context was disposed of after his method call. So if you are only using one entity context per HttpContext, make sure you don't allow the garbage collector to dispose of it by using a using block.
I figured I would throw this in the answers since I know a lot of people use the entity context differently and I see a lot of using blocks in code samples out there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With