web-dev-qa-db-fra.com

System.ObjectDisposedException: l'instance ObjectContext a été supprimée et ne peut plus être utilisée pour des opérations nécessitant une connexion.

J'utilise EF 4 pour récupérer une liste d'employés.

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

La liste est récupérée correctement, mais lorsque je la sérialise, je reçois cette 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)

Je trouve cela très étrange. J'ai déjà récupéré la liste des employés et le DataContext a été supprimé. Alors, pourquoi aurais-je cette erreur?

26
arame3333

Il semble que vous ayez des propriétés de relation paresseuses qui ne l’ont pas encore été (ce qui pose un problème de performance "n + 1" associé). Vous pouvez essayer chargement impatient pour voir si cela aide; sinon, chargez explicitement les données pour chaque élément de la liste, avant, vous fermez le contexte d'objet.

22
Marc Gravell

Vous pouvez désactiver le chargement paresseux pour résoudre ce problème.
Dans votre bloc 'using', essayez ceci:

yourObjectContext.ContextOptions.LazyLoadingEnabled = false;

Après cela, j'ai pu sérialiser mon POCO en JSON EF (généré par DbContext) sans aucun problème.

* Remarque: Depuis que j'ai désactivé le chargement différé ..., j'inscris explicitement les objets connexes dont j'ai besoin à l'avance (principalement avec .Include () dans ma requête) avant que l'objet ne soit sérialisé en JSON.

17
ClearCloud8

Je pensais que j'allais entrer ici avec mes 2 centimes. Nous avions une très grande couche d'accès aux données, et l'un des programmeurs était habitué à utiliser une instruction using pour le contexte, comme ceci:

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

Nous utilisons EntityConnection en tant que propriété statique servant un dbContext par HttpContext actuel. Toute méthode appelée après son bloc using lèverait l'exception 'l'instance d'ObjectContext a été supprimée' car il était évident que le contexte avait été supprimé après son appel de méthode. Ainsi, si vous n'utilisez qu'un seul contexte d'entité par HttpContext, veillez à ne pas autoriser le récupérateur de place à le supprimer à l'aide d'un bloc using.

J'ai pensé que je mettrais cela dans les réponses car je sais que beaucoup de gens utilisent le contexte de l'entité différemment et que je vois beaucoup utiliser des blocs dans les exemples de code. 

12
Mario

Je préfère charger une instance fat déclarée en dehors de l'utilisation 

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

Ensuite, je peux la transmettre à la vue ou à l’assistant qui la voulait vraiment.

2
ChristianProgrammer

J'ai eu le même problème et je pouvais le résoudre en sélectionnant une projection de l'objet avec uniquement les propriétés requises par l'appelant, au lieu de renvoyer l'objet complet . Il semble que lorsque vous avez plusieurs relations dans votre objet, le sérialiseur pour naviguer ceux-ci.

Donc, (en supposant que votre contexte d'objet s'appelle "Entities"), je voudrais essayer quelque chose comme ceci:

using ( Entities context = new Entities() )
{
       var employeeProjection = (from e in context.Employee
                         select new { e.Id, c.FirstName, e.LastName }).ToList();

        return employeeProjection;
 }
1
Maxolidean

Cela ressemble à une évaluation paresseuse ou retardée; vous ne pouvez pas supposer que les objets sont "chargés" jusqu'à ce que vous essayiez réellement de les lire.

Vous devez conserver votre DataContext jusqu'à ce que vous ayez complètement fini de manipuler les objets extraits de la base de données pour éviter ces erreurs.

1
Paul Turner

J'ai trouvé le meilleur moyen de gérer cela et de conserver la déclaration using dont vous avez juste besoin d'utiliser include, voir l'exemple ci-dessous:

using (var ctx = new Context(this.connectionString)) {
  var query = ctx.[maintable]
    .Include(x => x.[theothertable])
    .FirstOrDefaultAsync(u => u.UserName.Equals(userName));
}
0
Vazqusa

J'ai eu une variation sur ce problème. Le contexte de données n'a pas été fermé, mais l'instance de contexte d'objet a été supprimée. Une erreur a néanmoins été générée.

Il s'est avéré que l'objet avait une clé étrangère auto-référentielle (c'est-à-dire la clé étrangère renvoyée dans la même table). En accédant à la propriété de navigation dans le cas où elle fait référence à un null, vous obtenez une exception disposée par objectcontext au lieu, par exemple, d’une exception de pointeur null.

par exemple:

var a = myObject.Name; // works because myObject still has open object context
var b = myObject.SelfReference; // throws objectcontext disposed if SelfReference is null
0
user281806
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
jhaoui med

Je me permets d’examiner votre objet Employé et de vous assurer que votre mot-clé n’est pas virtuel. Le mot clé virtual est interprété par Entity Framework comme "lazy-load". Nous aurions besoin de voir votre classe Employé pour affirmer de manière absolue pourquoi vous pourriez voir l'exception.

0
Mr. Young