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