[英]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
的问题当我运行此代码时,出现错误
“因为
DbContext
已被处置,所以操作无法完成。”
我尝试按照建议在第3行的末尾添加.ToList()
,但随后出现错误
“序列化类型为System.Data.Entity.DynamicProxies的对象时检测到循环引用。”
这不是很明显,但是内置的Json
方法仅在JTask
方法完成执行后才进行序列化。 当然,到那时,上下文已经处理掉,导致您正在描述的原始错误。
如果您在Todo
类中具有ICollection<TodoItem>
属性,则每个属性都将具有ToDo
属性,该属性是对父级的引用。 每个ToDo
属性还将具有ICollection<TodoItem>
子级,这些子级又具有对父级的引用,依此类推。 这可能会无限循环,并且当序列化程序尝试序列化对象时,它会放弃循环引用错误。
同时解决这两个问题的一种方法是使用视图模型。 视图模型是一个中间类,仅包含模型类具有的属性的子集。 典型的流程是先将模型类转换为视图模型,然后将其序列化为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
由于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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.