it-swarm.com.de

System.ObjectDisposedException: Die ObjectContext-Instanz wurde verworfen und kann nicht mehr für Vorgänge verwendet werden, für die eine Verbindung erforderlich ist

Ich verwende EF 4, um eine Liste der Angestellten abzurufen.

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

Die Liste wird abgerufen, aber wenn ich sie serialisiere, erhalte ich diese Ausnahme.

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)

Ich finde das sehr seltsam. Ich habe bereits die Liste der Mitarbeiter abgerufen und der DataContext wurde gelöscht. Warum sollte ich diesen Fehler erhalten?

26
arame3333

Es klingt, als hätten Sie ein paar träge geladene Beziehungseigenschaften, die noch nicht geladen wurden (was ein "n + 1" -Leistungsproblem betrifft). Sie können versuchen, eifriges Laden zu sehen, ob dies hilft. Andernfalls laden Sie explizit die Daten für jedes Element in der Liste. Mit vorher schließen Sie den Objektkontext.

22
Marc Gravell

Sie können das langsame Laden deaktivieren, um dieses Problem zu beheben.
Versuchen Sie in Ihrem "using" -Block Folgendes:

yourObjectContext.ContextOptions.LazyLoadingEnabled = false;

Danach konnte ich mein EF (DbContext-generiertes) POCO ohne Probleme zu JSON serialisieren.

* Hinweis: Da ich Lazy Loading deaktiviert habe, ziehe ich explizit verwandte Objekte an, die vorab (meistens mit .Include () in meiner Abfrage) benötigt werden, bevor das Objekt in JSON serialisiert wird.

17
ClearCloud8

Ich dachte, ich würde hier mit meinen 2 Cent klingeln. Wir hatten eine sehr große Datenzugriffsebene, und einer der Programmierer war es gewohnt, eine using-Anweisung für den Kontext zu verwenden:

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

Wir verwenden EntityConnection als statische Eigenschaft, die pro aktuellem HttpContext einen dbContext bereitstellt. Jede nach dem using-Block aufgerufene Methode würde die Ausnahme 'ObjectContext-Instanz wurde gelöscht' auslösen, da offensichtlich der Kontext nach seinem Methodenaufruf beseitigt wurde. Wenn Sie also nur einen Entitätskontext pro HttpContext verwenden, stellen Sie sicher, dass der Garbage Collector nicht über einen using-Block entsorgt werden darf.

Ich dachte mir, ich würde dies in die Antworten einwerfen, da ich weiß, dass viele Leute den Entitätskontext anders verwenden und ich sehe sehr viele Blöcke in Codebeispielen. 

12
Mario

Ich ziehe es vor, nur eine fette Instanz zu laden, die außerhalb der Verwendung deklariert wurde 

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

Dann kann ich sie auf die View oder den Helfer geben, der sie wirklich wollte.

2

Ich hatte das gleiche Problem und konnte es lösen, indem ich eine Projektion des Objekts mit nur den vom Aufrufer gewünschten Eigenschaften auswählte, anstatt das vollständige Objekt zurückzugeben. Es scheint, dass der Serialisierer versucht, wenn Sie viele Beziehungen in Ihrem Objekt haben um diese zu navigieren.

(Angenommen, Ihr Objektkontext heißt "Entitäten"), würde ich Folgendes versuchen:

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

Es klingt wie ein verzögertes Laden oder verzögerte Auswertung. Sie können nicht davon ausgehen, dass Objekte "geladen" werden, bis Sie tatsächlich versuchen, von ihnen zu lesen.

Sie müssen Ihre DataContext beibehalten, bis Sie die aus der Datenbank abgerufenen Objekte vollständig bearbeitet haben, um diese Fehler zu vermeiden.

1
Paul Turner

Ich habe den besten Weg gefunden, damit umzugehen und die using-Anweisung beizubehalten, die Sie nur für das Include benötigen.

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

Ich hatte eine Variation dieses Problems. Der Datenkontext wurde nicht geschlossen, aber die Objektkontextinstanz wurde gelöscht, obwohl der Fehler trotzdem ausgegeben wurde.

Es stellte sich heraus, dass das Objekt einen selbstreferenziellen Fremdschlüssel hatte (dh der Fremdschlüssel, der in dieselbe Tabelle zurückverweist). Wenn Sie auf die Navigationseigenschaft zugreifen, wenn sie sich auf eine Null bezieht, erhalten Sie die Ausnahmebedingung objectcontext statt einer Nullzeiger-Ausnahme.

z.B:

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

Es lohnt sich, einen Blick auf Ihr Employee-Objekt zu werfen und sicherzustellen, dass Sie keine virtuellen Schlüsselwörter haben. Das virtuelle Schlüsselwort wird von Entity Framework als "Lazy-Load" interpretiert. Wir müssten Ihre Employee-Klasse sehen, um eine absolute Behauptung zu machen, warum Sie die Ausnahme sehen könnten.

0
Mr. Young