2016-08-01 32 views
2
public JsonResult JTask(int id) 
{ 
    using (TestDb db = new TestDb()) 
    { 
     var a = db.ToDos.Where(todo => todo.UserId == id); 
     return Json(a, JsonRequestBehavior.AllowGet); 
    } 
} 

entsorgt Ich habe ein Problem mit der Rückkehr JsonResult Wenn ich diesen Code Code ausführen erhalte ich die FehlerFehler: DbContext wurde

"The operation cannot be completed because the DbContext has been disposed."

Ich versuchte .ToList() am Ende der Leitung 3 hinzufügen, wie die Daten wurden vorgeschlagen, aber dann bekam ich den Fehler

"A circular reference was detected while serializing an object of type System.Data.Entity.DynamicProxies."

+0

Sie benötigen die 'ToList' am Ende, weil offensichtlich die Abfrage nicht ausgeführt wird, bis es * ausgewertet *. Der Grund, warum Sie einen Zirkelverweis erhalten, liegt vermutlich daran, dass Sie ein Modell mit einer Navigationseigenschaft für ein anderes Modell mit einer Rückseite haben. In diesem Fall müssen Sie MVC oder WebApi JSON Serialiser einrichten, um Referenzschleifen zu ignorieren. –

+0

Wie machen Sie JSON-Serialisierung? Richten Sie es in der Global.asax oder so etwas ein? –

+0

Verwenden Sie den Javascriptserializer oder JSON.Net? –

Antwort

2

Es ist nicht sehr offensichtlich, aber die Json Methode in-built tut nur die Serialisierung nachdem die Methode JTask die Ausführung beendet hat. Zu diesem Zeitpunkt wurde der Kontext natürlich entfernt, was zu dem ursprünglichen Fehler führt, den Sie beschreiben.

Wenn Sie eine ICollection<TodoItem> Eigenschaft in Ihrer Todo Klasse, jeder von denen wird eine ToDo Eigenschaft, die eine Referenz auf den übergeordneten ist. Und jede dieser ToDo Eigenschaften wird auch ICollection<TodoItem> Kinder haben, die eine Referenz zurück zum Elternteil hat, und so weiter und so fort. Dies kann möglicherweise für unendlich fortlaufen, und wenn der Serializer versucht, das Objekt zu serialisieren, gibt es einen kreisförmigen Referenzfehler auf.

Eine Möglichkeit, beide Probleme gleichzeitig zu lösen, ist die Verwendung von Viewmodels. Ein Viewmodel ist eine Zwischenklasse, die nur eine Teilmenge der Eigenschaften einer Modellklasse enthält. Der typische Fluss ist für die Modellklasse zuerst auf ein Ansichtsmodell konvertierte zu bekommen, dann wäre es das Ansichtsmodell sein, das als Json serialisiert wird:

var viewModels = new List<TodoViewModel>(); 

using (TestDb db = new TestDb()) 
{ 
    var todoModels = db.ToDos.Where(todo => todo.UserId == id).ToList(); 

    foreach (var model in todoModels) 
    { 
     var todoViewModel = new TodoViewModel 
     { 
      // Populate viewmodel properties here 
      Text = model.Text 
     }; 

     viewModels.Add(todoViewModel); 
    } 
} 

return Json(viewModels, JsonRequestBehavior.AllowGet); 

ich einen Blog-Post über die Vorteile der Verwendung von Viewmodels schrieb. Sie können es hier auschecken, wenn Sie interessiert sind: Why Use ViewModels

+0

Vielen Dank So viel! :) Du hast mir sehr geholfen. Ich stecke seit mehreren Stunden fest :) –

+0

Kein Problem. Willkommen (zurück) zu StackOverflow! :) –

1

Da Linq durch die Zeit, die JSON versucht faul ist auszu bekommen(und nur dann tatsächlich geht zu db) hat die db bereits entsorgt worden - wenn sie den Umfang der using

verlassen
public JsonResult JTask(int id) 
{ 
    using (TestDb db = new TestDb()) 
    { 
     var a = db.ToDos.Where(todo => todo.UserId == id).ToList(); 
     return Json(a, JsonRequestBehavior.AllowGet); 
    } 
} 
+0

IEnumerables kann faul sein, dies ist nicht die ganze Antwort obwohl –

+0

Jetzt habe ich das Problem mit "Eine zirkuläre Referenz wurde beim Serialisieren eines Objekts vom Typ" Kannst du mi mit Serialisierung helfen? Ich bin mir nicht sicher, wie es richtig zu machen ist –

0
var a = db.ToDos.Where(todo => todo.UserId == id).ToList();