2016-08-01 4 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); 
    } 
} 

が配置されてきた私は、私のように、3行目の末尾に.ToList()を追加しようとした私は、このコードのコードを実行すると、私はエラーにエラー:DbContextは

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

を取得JsonResult を返すに問題があります提案されたが、その後、私はエラーを得た

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

+0

をそれを取得するまで明らかにクエリが実行されませんので、あなたは*を評価*、最後に 'ToList'が必要になります。しかし、循環参照を取得している理由は、別のモデルにナビゲーションプロパティを持つモデルが1つ戻るためです。この場合、あなたはどのように直列化JSONを行っている参照ループ –

+0

を無視するMVCやWEBAPI JSONのシリアライザを設定する必要がありますか?あなたはGlobal.asaxなどで設定していますか? –

+0

JavascriptserializerまたはJSON.Netを使用していますか? –

答えて

2

の範囲を出るとき、それは非常に明白ではないですが、内蔵のJson方法が唯一の直列化を行いますJTaskメソッドの実行が終了した後その時までに、コンテキストは破棄され、元のエラーとなります。

Todoクラス内にICollection<TodoItem>プロパティがある場合、それらのそれぞれには親の参照先のToDoプロパティがあります。そして、それらのToDoの各プロパティはまたようになど、再び親への参照を持っており、これは、ICollection<TodoItem>子供を持つことになります。これは潜在的に無限大にループする可能性があり、シリアライザがオブジェクトを直列化しようとすると循環参照エラーが発生します。同時に、これらの問題の両方を解決する

一つの方法は、のviewmodelsを使用することです。ビューモデルは、モデルクラスが持つプロパティのサブセットのみを保持する中間クラスです。モデルクラスは、最初のviewmodelに変換取得するための典型的な流れは、それがJSONとしてシリアル化されますのviewmodelになり、次のとおりです。

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

私はのviewmodelsを使用することの利点についてのブログ記事を書きました。もし興味があるなら、あなたはここでそれをチェックアウトすることができます:Why Use ViewModels

+0

はありがとう適切な方法を行う方法がわからないんだけどあなたは私をたくさん助けました。私はこれに数時間こだわっています:) –

+0

問題はありません。 StackOverflowへようこそ! :) –

1

LINQのは、時間によってレイジーなのでJSON試みは、のうちデータを取得します(だけにして、実際にdbに行く)dbが既に破棄されている - using

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は怠惰することができ、この –

+0

は、今私は はあなたがシリアライズとMI助けることができる「タイプのオブジェクトをシリアル化しながら、循環参照が検出されました」との問題を抱えているものの、全体の答えではないのですか?私はそれを –

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