错误: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。">

错误:DbContext已被释放

这不是很明显,但内置的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();