MVC 3 - ObjectContext实例已被释放,不能再用于需要连接的操作

Joh*_*n H 5 c# dispose objectcontext asp.net-mvc-3

我对C#和MVC很新,我一直在创建自己的小博客网站作为测试项目.虽然大多数事情都在发挥作用,但我在从LINQ查询中选择多个列时遇到了问题.只有在关于SO的问题上磕磕绊绊之后我才意识到我可以使用生成的实体类作为强类型模型来处理这个问题.我需要这个,因为我一直在创建一个数据库层(这也是我之前没有用过的东西)并试图通过该层传递匿名类型不起作用.我理解为什么会这样,所以我很满意我正朝着正确的方向前进.

然而,这种方法似乎给了我另一个问题.我尝试过一个简单的测试,从我的Categories表中检索2列:CategoryID和Name.我最初尝试了以下内容:

using (MyEntities db = new MyEntities())
{
    var model = from c in db.Categories
                select new Category { CategoryID = c.CategoryID, Name = c.Name };

    return View(model);
}
Run Code Online (Sandbox Code Playgroud)

这给了我在尝试迭代视图中的模型时ObjectContext被置错的错误.在阅读完这个问题后,我尝试将return语句移到using块之外,并在模型上调用AsEnumerable(),如下所示:

IEnumerable<Category> model;

using (MyEntities db = new MyEntities())
{
    model = from c in db.Categories
            select new Category { CategoryID = c.CategoryID, Name = c.Name };
}

return View(model.AsEnumerable());
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试在视图中迭代模型时,这仍然给我相同的ObjectContext处置错误.所以现在我不明白我为什么会收到这个错误.我甚至尝试完全删除using指令,但这给了我一个不同的错误:

"无法在LINQ to Entities查询中构造实体或复杂类型'MyProjectModel.Category'."

如果有帮助,这是我的观点的相关代码:

@model IEnumerable<MyProject.Models.Category>

@foreach (var category in Model)
{
    <p>@category.Name</p>
}
Run Code Online (Sandbox Code Playgroud)

有人会善意地告诉我我错过了什么吗?

谢谢.

Dar*_*rov 12

.ToList()在处理之前急于控制器并调用,以便在离开using块之前立即执行查询(之后为时已晚,上下文消失了):

using (MyEntities db = new MyEntities())
{
    var model = 
        from c in db.Categories
        select new Category 
        { 
            CategoryID = c.CategoryID, 
            Name = c.Name 
        };
    return View(model.ToList()); // <-- .ToList() here
}
Run Code Online (Sandbox Code Playgroud)

现在,虽然这将解决您的特定问题,但开发人员或依赖注入框架通常做的是实例化事件DbContext内部BeginRequest,将其存储在内部,HttpContext.Items以便在整个请求的执行过程中可用,并在EndRequest方法内部检索它HttpContext并处置它.


更新:

此外,最好使用仅包含您要在此特定视图中使用的属性的视图模型:

public class CategoryViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的行动中:

public ActionResult Index()
{
    using (MyEntities db = new MyEntities())
    {
        var model = 
            from c in db.Categories
            select new CategoryViewModel
            { 
                Id = c.CategoryID, 
                Name = c.Name 
            };
        return View(model.ToList());
    }
}
Run Code Online (Sandbox Code Playgroud)

并在视图中:

@model IEnumerable<MyProject.Models.CategoryViewModel>

@foreach (var category in Model)
{
    <p>
        Id: @category.Id 
        Name: @category.Name
    </p>
}
Run Code Online (Sandbox Code Playgroud)