我对 ASP.NET MVC 应用程序中 Entity Framework 上下文的预期生命周期有一些疑问。在尽可能短的时间内保持上下文事件不是最好的吗?
考虑以下 Controller 操作:
public ActionResult Index()
{
IEnumerable<MyTable> model;
using (var context = new MyEntities())
{
model = context.MyTable;
}
return View(model);
}
上面的代码将不起作用,因为 Entity Framework 上下文在 View 呈现页面时超出了范围。其他人会如何构造上面的代码?
最佳答案
让我们开始争论吧!
我不同意一般的 MVC + EF 共识,即在整个请求中保持上下文事件是一件好事,原因有很多:
低性能提升 你知道创建一个新的数据库上下文有多昂贵吗?嗯...“DataContext 是轻量级的,创建起来并不昂贵”,来自 MSDN
如果 IoC 错误,它看起来会很好......直到你上线 如果您设置 IoC 容器来为您处理上下文,但您弄错了,那您就真的弄错了。我现在已经两次 看到从 IoC 容器创建的大量内存泄漏并不总是正确处理上下文。在您的服务器在正常水平的并发用户期间开始崩溃之前,您不会意识到您设置错误。它不会在开发中发生,所以做一些负载测试!
意外延迟加载 您返回最近文章的 IQueryable,以便您可以将它们列在主页上。有一天,其他人被要求在相应文章旁边显示评论数。所以他们添加了一些简单的代码到 View 来显示评论数,就像这样......
@foreach(var article in Model.Articles) {
<div>
<b>@article.Title</b> <span>@article.Comments.Count() comments</span>
</div>
}
看起来不错,工作正常。但实际上您没有在返回的数据中包含评论,所以现在这将为循环中的每篇文章进行新的数据库调用。选择 N+1 个问题。 10 篇文章 = 11 次数据库调用。好吧,代码是错误的,但这是一个很容易犯的错误,所以它会发生。
您可以通过关闭数据层中的上下文来防止这种情况发生。但是代码不会因 article.Comments.Count() 上的 NullReferenceException 而中断吗?是的,它会强制您编辑 Data 层以获取 View 层所需的数据。这是应该的。
代码味道 从您的 View 访问数据库只是出了点问题。您知道 IQueryable 还没有真正访问数据库,所以忘记那个对象吧。确保您的数据库在离开数据层之前已被命中。
所以答案
你的代码应该(在我看来)是这样的
数据层:
public List<Article> GetArticles()
{
List<Article> model;
using (var context = new MyEntities())
{
//for an example I've assumed your "MyTable" is a table of news articles
model = (from mt in context.Articles
select mt).ToList();
//data in a List<T> so the database has been hit now and data is final
}
return model;
}
Controller :
public ActionResult Index()
{
var model = new HomeViewModel(); //class with the bits needed for you view
model.Articles = _dataservice.GetArticles(); //irrelevant how _dataService was intialised
return View(model);
}
一旦你完成并理解了这一点,那么你也许可以开始尝试使用 IoC 容器处理上下文,但绝对不是之前。请注意我的警告 - 我见过两次大规模失败:)
但老老实实做自己喜欢的事,编程很有趣,应该是一个偏好的问题。我只是告诉你我的。但是无论您做什么,都不要仅仅因为“所有酷 child 都在这样做”就开始为每个 Controller 或每个请求使用 IoC 上下文。这样做是因为您真正关心它的好处并了解如何正确完成。
关于c# - 关于Entity Framework Context Lifetime的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10777630/