错误:DbContext已被处置

时间:2016-08-01 08:04:51

标签: c# entity-framework linq dbcontext jsonresult

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“。

3 个答案:

答案 0 :(得分:2)

这不是很明显,但内置Json方法仅在JTask方法执行完毕后才进行序列化。当然,到那时,上下文已被处理掉,导致你所描述的原始错误。

如果您的ICollection<TodoItem>课程中有Todo个属性,则每个属性都会有一个ToDo属性,该属性是对父级的引用。并且每个ToDo属性中也会有ICollection<TodoItem>个子项,它们会再次引用父项,依此类推。这可能会为无穷大循环,当序列化程序尝试序列化对象时,它会放弃循环引用错误。

同时解决这两个问题的一种方法是使用viewmodels。 viewmodel是一个中间类,它只包含模型类具有的属性的子集。典型的流程是模型类首先转换为viewmodel,然后它将是被序列化为json的viewmodel:

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的优点的博文。如果您有兴趣,可以在这里查看:Why Use ViewModels

答案 1 :(得分:1)

因为当JSON尝试从a中获取数据时,Linq是懒惰的(并且实际上仅转到dbdb已经存在处置 - 离开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);
    }
}

答案 2 :(得分:0)

python setup.py develop