MVC 3-ObjectContext实例已被释放,不能再用于需要连接的操作
本文关键字:用于 连接 操作 不能 实例 3-ObjectContext 释放 MVC | 更新日期: 2023-09-27 17:59:41
我对C#和MVC很陌生,我一直在创建自己的小博客网站作为测试项目。尽管到目前为止,大多数事情都在进行,但我在从LINQ查询中选择多个列时遇到了问题。直到在SO上遇到一个问题后,我才意识到我可以使用生成的实体类作为强类型模型来处理这个问题。我需要这个,因为我一直在创建一个数据库层(这也是我以前从未使用过的),并且试图通过该层传递匿名类型是不起作用的。我理解为什么会这样,所以我很满意我正朝着正确的方向前进。
然而,这种做法似乎给我带来了另一个问题。我尝试了一个简单的测试来从Categories表中检索两列: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);
}
这让我在尝试迭代视图中的模型时出现了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());
然而,当我尝试迭代视图中的模型时,这仍然会给我带来相同的ObjectContext被丢弃错误。所以现在我不明白为什么我会出错。我甚至尝试过完全删除using指令,但这给了我一个不同的错误:
"无法在LINQ to Entities查询中构造实体或复杂类型"MyProjectModel.Category"。"
如果有帮助的话,下面是我观点的相关代码:
@model IEnumerable<MyProject.Models.Category>
@foreach (var category in Model)
{
<p>@category.Name</p>
}
有人能告诉我我缺少了什么吗?
谢谢。
在控制器中等待并在处理前调用.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
}
现在,虽然这将解决您的特定问题,但开发人员或依赖注入框架通常要做的是在BeginRequest
事件中实例化DbContext
,将其存储在HttpContext.Items
中,以便在整个请求的执行过程中和EndRequest
方法中都可以使用,从HttpContext
中检索并处理它。
更新:
此外,使用仅包含您希望在此特定视图中使用的属性的视图模型也是一种很好的做法:
public class CategoryViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
然后进入你的行动:
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());
}
}
并且在视图中:
@model IEnumerable<MyProject.Models.CategoryViewModel>
@foreach (var category in Model)
{
<p>
Id: @category.Id
Name: @category.Name
</p>
}