Error: DbContext has been disposed
Error: DbContext has been disposed
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
当我 运行 此代码代码时,我得到错误
"The operation cannot be completed because the DbContext
has been
disposed."
我尝试按照建议在第 3 行的末尾添加 .ToList()
,但随后出现错误
"A circular reference was detected while serializing an object of type
System.Data.Entity.DynamicProxies."
因为 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);
}
}
var a = db.ToDos.Where(todo => todo.UserId == id).ToList();
不是很明显,但是内置的Json
方法只是在JTask
方法执行完之后才进行序列化。到那时,当然,上下文已经被处理,导致您描述的原始错误。
如果您的 Todo
class 中有一个 ICollection<TodoItem>
属性,那么每个人都会有一个 ToDo
属性,即对父级的引用。每个 ToDo
属性也将有 ICollection<TodoItem>
个子属性,这些子属性再次指向父属性,依此类推。这可能会无限循环,当序列化程序尝试序列化对象时,它会因循环引用错误而放弃。
同时解决这两个问题的一种方法是使用视图模型。视图模型是一个中间体 class,它仅包含模型 class 具有的属性的子集。典型的流程是先将模型 class 转换为视图模型,然后将视图模型序列化为 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);
我写了一篇博客 post 关于使用视图模型的优势。如果您有兴趣,可以在这里查看:Why Use ViewModels
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
当我 运行 此代码代码时,我得到错误
"The operation cannot be completed because the
DbContext
has been disposed."
我尝试按照建议在第 3 行的末尾添加 .ToList()
,但随后出现错误
"A circular reference was detected while serializing an object of type System.Data.Entity.DynamicProxies."
因为 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);
}
}
var a = db.ToDos.Where(todo => todo.UserId == id).ToList();
不是很明显,但是内置的Json
方法只是在JTask
方法执行完之后才进行序列化。到那时,当然,上下文已经被处理,导致您描述的原始错误。
如果您的 Todo
class 中有一个 ICollection<TodoItem>
属性,那么每个人都会有一个 ToDo
属性,即对父级的引用。每个 ToDo
属性也将有 ICollection<TodoItem>
个子属性,这些子属性再次指向父属性,依此类推。这可能会无限循环,当序列化程序尝试序列化对象时,它会因循环引用错误而放弃。
同时解决这两个问题的一种方法是使用视图模型。视图模型是一个中间体 class,它仅包含模型 class 具有的属性的子集。典型的流程是先将模型 class 转换为视图模型,然后将视图模型序列化为 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);
我写了一篇博客 post 关于使用视图模型的优势。如果您有兴趣,可以在这里查看:Why Use ViewModels