错误:DbContext已被释放
本文关键字:释放 DbContext 错误 | 更新日期: 2023-09-27 17:59:41
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
因为当JSON
试图从a
获取数据时(然后才真正转到db
(,Linq是Lazy,所以当离开using
的范围时,db
已经被处理
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();