简体   繁体   English

错误:DbContext已被处置

[英]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);
    }
}

I have a problem with returning JsonResult When I run this code code I get the error 我有返回JsonResult的问题当我运行此代码时,出现错误

"The operation cannot be completed because the DbContext has been disposed." “因为DbContext已被处置,所以操作无法完成。”

I tried adding .ToList() at the end of the line 3, as was suggested, but then I got the error 我尝试按照建议在第3行的末尾添加.ToList() ,但随后出现错误

"A circular reference was detected while serializing an object of type System.Data.Entity.DynamicProxies." “序列化类型为System.Data.Entity.DynamicProxies的对象时检测到循环引用。”

It's not very obvious, but the built-in Json method only does the serialization after the JTask method has finished executing. 这不是很明显,但是内置的Json方法仅在JTask方法完成执行后才进行序列化。 By that time, of course, the context has been disposed, resulting in the original error you are describing. 当然,到那时,上下文已经处理掉,导致您正在描述的原始错误。

If you have an ICollection<TodoItem> property inside your Todo class, each of those will have a ToDo property which is a reference back to the parent. 如果您在Todo类中具有ICollection<TodoItem>属性,则每个属性都将具有ToDo属性,该属性是对父级的引用。 And each of those ToDo properties will also have ICollection<TodoItem> children, which has a reference back to the parent again, and so on and so forth. 每个ToDo属性还将具有ICollection<TodoItem>子级,这些子级又具有对父级的引用,依此类推。 This can potentially loop for infinity, and when the serializer tries to serialize the object, it gives up with a circular reference error. 这可能会无限循环,并且当序列化程序尝试序列化对象时,它会放弃循环引用错误。

One way to solve both of these problems at the same time is by using viewmodels. 同时解决这两个问题的一种方法是使用视图模型。 A viewmodel is an intermediate class that holds only a subset of the properties that a model class has. 视图模型是一个中间类,仅包含模型类具有的属性的子集。 The typical flow is for the model class to get converted to a viewmodel first, then it would be the viewmodel that gets serialized as json: 典型的流程是先将模型类转换为视图模型,然后将其序列化为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);

I wrote a blog post about the advantages of using viewmodels. 我写了一篇关于使用视图模型的优势的博客文章。 You can check it out here if you're interested: Why Use ViewModels 如果您有兴趣,可以在这里查看: 为什么使用ViewModels

Because Linq is Lazy by the time the JSON tries to get the data out of a (and only then actually goes to db ) the db has already been disposed - when leaving the scope of the using 由于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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM