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

У меня есть проблема с возвращением JsonResult Когда я запускаю этот код код, который я получаю ошибкуОшибка: DbContext были захоронены

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

Я попытался добавить .ToList() в конце строки 3, как было предложено, но потом я получил ошибку

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

+0

Вам нужно будет 'ToList' на конце, потому что очевидно, что запрос не будет выполняться до тех пор, пока он не получит * оцененный *. Тем не менее, причина, по которой вы получаете круговую ссылку, я предполагаю, потому что у вас есть модель, которая имеет свойство навигации для другой модели, у которой есть одна спина. В этом случае вам нужно настроить MVC или WebApi JSON-сериализатор для игнорирования опорных циклов. –

+0

Как вы делаете сериализацию JSON? Вы настраиваете его в Global.asax или что-то в этом роде? –

+0

Вы используете Javascriptserializer или JSON.Net? –

ответ

2

Это не очень очевидно, но встроенный в Json метод делает только сериализации после завершения метода JTask. К тому времени, конечно, контекст был удален, что привело к исходной ошибке, которую вы описываете.

Если у вас есть ICollection<TodoItem> свойства внутри вашего Todo класса, каждый из которых будет иметь ToDo свойства, которое является ссылкой обратно к родителю. И каждый из этих ToDo объектов также будет иметь детей ICollection<TodoItem>, которые снова возвращаются к родителям и т. Д. И т. Д. Это может потенциально зацикливаться на бесконечность, и когда сериализатор пытается сериализовать объект, он отказывается от круговой контрольной ошибки.

Одним из способов решения обеих этих проблем в одно и то же время является использование режимов просмотра. Viewmodel - это промежуточный класс, который содержит только подмножество свойств, которые имеет класс модели. Типичный поток для класса модели, чтобы получить преобразованный в ViewModel первым, то это будет ViewModel, который получает сериализовать JSON:

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 пытается получить данные из a (и только тогда на самом деле идет в 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();