MVC 3 - ObjectContext 实例已被释放,不能再用于需要连接的操作
一般来说,我对 C# 和 MVC 非常陌生,我一直在创建自己的小博客网站作为测试项目。尽管到目前为止大多数事情都正常,但我在从 LINQ 查询中选择多个列时遇到了问题。只是在偶然发现 SO 上的一个问题之后,我才意识到我可以使用生成的实体类作为强类型模型来处理这个问题。我需要这个,因为我一直在创建数据库层(这也是我以前没有使用过的东西)并且尝试通过该层传递匿名类型不起作用。我明白为什么会出现这种情况,所以我很满意我正朝着正确的方向前进。
然而,这种做法似乎又给我带来了另一个问题。我尝试了一个简单的测试,从“类别”表中检索 2 列:“类别 ID”和“名称”。我最初尝试了以下操作:
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 is Dispose 错误。阅读这个问题后,我尝试将 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 is Dispose 错误。所以现在我不明白为什么我会收到错误。我什至尝试完全删除 using 指令,但这给了我一个不同的错误:
“实体或复杂类型‘MyProjectModel.Category’无法在 LINQ to Entities 查询中构造。”
如果有帮助,这里是我的观点的相关代码:
@model IEnumerable<MyProject.Models.Category>
@foreach (var category in Model)
{
<p>@category.Name</p>
}
有人愿意告诉我我缺少什么吗?
谢谢。
I'm very new to C# and MVC in general and I've been creating my own little blog site as a test project. Although most things are working up to this point, I have had problems selecting multiple columns from LINQ queries. It was only after stumbling on a question on SO that I realised I could use the generated entities classes as strongly-typed models to handle this. I've needed this as I've been creating a database layer (which is also something I've not used before) and trying to pass anonymous types through that layer didn't work. I understand why that was the case, so I'm satisfied that I'm heading in the right direction.
However, this approach seems to have given me another problem. I've tried a simple test to retrieve 2 columns from my Categories table: CategoryID and Name. I initially tried the following:
using (MyEntities db = new MyEntities())
{
var model = from c in db.Categories
select new Category { CategoryID = c.CategoryID, Name = c.Name };
return View(model);
}
This gave me the ObjectContext is disposed error when trying to iterate over the model in the view. After reading this question, I tried moving the return statement outside of the using block and calling AsEnumerable() on the model like so:
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());
However, this is still giving me the same ObjectContext is disposed error when I try to iterate over the model in the view. So now I don't understand why I'm getting the error. I've even tried removing the using directive completely but that gives me a different error:
"The entity or complex type 'MyProjectModel.Category' cannot be constructed in a LINQ to Entities query."
If it helps, here's the relevant code for my view:
@model IEnumerable<MyProject.Models.Category>
@foreach (var category in Model)
{
<p>@category.Name</p>
}
Would someone be kind enough to enlighten me as to what I'm missing?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在控制器中急于并在处理之前调用
.ToList()
,以便在离开using
块之前立即安排查询的执行(就像之后那样)太晚了,上下文已经消失了):现在,虽然这可以解决您的特定问题,但开发人员或依赖注入框架通常会在
BeginRequest
事件中实例化DbContext
,将其存储在HttpContext.Items
以便它在整个请求的执行过程中可用,并且在EndRequest
方法内,从HttpContext
检索它并释放它。更新:使用
仅包含您想在该特定视图中使用的属性的视图模型也是一个很好的做法:
然后在您的操作中:
和视图中:
Be eager in the controller and call
.ToList()
before disposing in order to schedule the execution of the query immediately before you have left theusing
block (as after that it is too late, the context is gone):Now, while this will solve your particular problem, what developers or dependency injection frameworks usually do is to instantiate the
DbContext
inside theBeginRequest
event, store it inside theHttpContext.Items
so that it is available throughout the execution of the entire request and inside theEndRequest
method, retrieve it fromHttpContext
and dispose it.UPDATE:
Also it is a good practice to use a view model containing only the properties you would like to use in this particular view:
and then inside your action:
and in the view: