System.ObjectDisposedException: экземпляр ObjectContext был удален и больше не может использоваться для операций, требующих подключения - PullRequest
27 голосов
/ 17 ноября 2010

Я использую EF 4 для получения списка сотрудников.

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

Список получен нормально, но когда я сериализую его, я получаю это исключение;

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)

Я нахожу это очень странным. Я уже получил список сотрудников, и DataContext был удален. Так почему бы мне получить эту ошибку?

Ответы [ 10 ]

24 голосов
/ 17 ноября 2010

Похоже, у вас есть некоторые лениво загруженные свойства отношений, которые еще не загружены (что связано с проблемой производительности "n + 1").Вы можете попробовать нетерпеливая загрузка , чтобы увидеть, поможет ли это;в противном случае явно загрузите данные для каждого элемента в списке, за до вы закроете объект-контекст.

17 голосов
/ 20 сентября 2012

Вы можете отключить отложенную загрузку, чтобы решить эту проблему.
Внутри блока 'using' попробуйте следующее:

yourObjectContext.ContextOptions.LazyLoadingEnabled = false;

После этого я смог сериализовать свой EF (DbContext-сгенерировано) POCO в JSON без каких-либо проблем.

* Примечание. Поскольку я отключил отложенную загрузку ... Я явно извлекаю связанные объекты, которые мне нужны, заранее (в основном, с помощью .Include () в моем запросе) до сериализации объекта в JSON.

12 голосов
/ 14 июня 2011

Думал, что я перезвоню здесь с моими 2 центами.У нас был очень большой уровень доступа к данным, и один из программистов привык использовать выражение для контекста следующим образом:

using (EntityModel myContext = EntityConnection)
{
    //code in here to grab data
}

Мы используем EntityConnection в качестве статического свойства, которое обслуживает dbContext.за текущий HttpContext.Любой метод, вызванный после его использования блока, вызовет исключение «экземпляр ObjectContext был удален», поскольку очевидно, что контекст был удален после вызова его метода.Так что, если вы используете только один контекст сущности для HttpContext, убедитесь, что вы не разрешаете сборщику мусора избавляться от него с помощью блока using.

Я подумал, что добавлю это в ответы, поскольку знаюмногие люди используют контекст сущности по-разному, и я вижу много примеров использования блоков в примерах кода.

2 голосов
/ 31 декабря 2011

Я предпочитаю просто загрузить толстый экземпляр, объявленный вне использования

   Customer _custObj;
        using (RazorOne rz1 = new RazorOne())
        {
             _custObj = rz1.Customers.FirstOrDefault();      //  .Include = Lazy loading
            // Versus Implicit Load
            _custObj.AddressReference.Load();
             _custObj.Address1Reference.Load();
        }

Тогда я могу передать ее на Вид или тому, что помощник действительно хотел ее ..

1 голос
/ 27 января 2011

У меня была та же проблема, и я мог ее решить, выбрав проекцию объекта только с теми свойствами, которые требуются вызывающей стороне, вместо того, чтобы возвращать полный объект.Кажется, что когда у вас много отношений в вашем объекте, сериализатор пытается перемещаться по ним.

Итак, (предположив, что ваш объектный контекст называется "Entities"), я бы попробовал что-то вроде этого:1004 *

1 голос
/ 17 ноября 2010

Похоже, что происходит какая-то отложенная или отложенная оценка;Вы не можете предполагать, что объекты «загружены» до тех пор, пока вы фактически не попытаетесь прочитать их.

Вам необходимо сохранять DataContext до тех пор, пока вы полностью не закончите обработку объектов, извлеченных из базы данных, чтобы избежать этих ошибок.

0 голосов
/ 29 октября 2018
using (EmployeeContext db= new EmployeeContext())
    {
        var lst = db.Employees.Select(p=> new {
            EmployeeID = p.EmployeeID,
            Name = p.Name,
            Salary = p.Salary,
            Position = p.Position,
            Age = p.Age,
            Office = p.Office
        }).ToList();
        return Json(lst, JsonRequestBehavior.AllowGet);
    }
0 голосов
/ 26 июня 2017

Я нашел лучший способ справиться с этим и сохранил оператор использования, который вам просто необходим для использования включения, см. Пример ниже:

using (var ctx = new Context(this.connectionString)) {
  var query = ctx.[maintable]
    .Include(x => x.[theothertable])
    .FirstOrDefaultAsync(u => u.UserName.Equals(userName));
}
0 голосов
/ 22 июля 2014

У меня была вариация на эту проблему. Контекст данных не был закрыт, но экземпляр контекста объекта был удален. В любом случае выдается ошибка.

Оказалось, что объект имеет собственный ссылочный внешний ключ (то есть внешний ключ, возвращенный в ту же таблицу). Получая доступ к свойству навигации в случае, когда оно ссылается на ноль, вы получаете исключение распоряжения объектного контекста вместо, скажем, исключения нулевого указателя.

например:

var a = myObject.Name; // works because myObject still has open object context
var b = myObject.SelfReference; // throws objectcontext disposed if SelfReference is null
0 голосов
/ 30 января 2013

Стоит взглянуть на ваш объект Employee и убедиться, что у вас нет виртуальных ключевых слов. Виртуальное ключевое слово интерпретируется Entity Framework как «ленивая загрузка». Нам нужно увидеть ваш класс Employee, чтобы сделать абсолютное утверждение, почему вы могли видеть исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...