entity frameworkDataContext关注 – 它是否在我的控制器中正确处理?

我已经交了一些代码,在控制器类中有一个属性,用于保存初始化的数据库上下文。

public class MyController: Controller { protected AssetManagerContext db = new AssetManagerContext("ConnectionString"); // Actions...etc. [HttpGet] public ActionResult Edit(int id) { MyAsset myAsset = db.Assets.Find(id); // Used and not disposed return View(myAsset); } } 

大多数操作使用此Context而不进行处理,我担心的是上下文保持开放。

  1. 我是否需要关注此上下文未被显式关闭(通过.Dispose()或using {}语句

  2. 如果我应该担心,我应该如何处理这种情况,因为变量是类的一部分并在操作中使用?

Controller类有一个dispose方法。 因此,在控制器中覆盖该方法并处理该上下文。

 protected override void Dispose(bool disposing) { base.Dispose(disposing); db.Dispose(); } 

在上下文完成后将自动调用它。

在调用控制器之间保持上下文打开绝不是一个好主意。

这导致DB连接被保持,直到GC处理MyController实例。

如果你的控制器完成了与Entity Framework的所有交互(你的视图不需要懒惰加载域对象),最简单的模式是

 public class MyController : Controller { public ActionResult MyAction(...) { using (AssetManagerContext db = new AssetManagerContext("ConnectionString")) { // Do stuff } } } 

如果您的视图确实需要从上下文中延迟加载对象,您确实可以将对上下文对象的引用作为类的属性,并按照@Kundan的建议实现IDisposable。

实际上,它并不重要。 正如斯蒂芬沃尔特在评论中发布他的一篇博客文章的链接时指出的那样 ,清理数据上下文并不是特别重要,因为最终,数据上下文在管理自己的连接和汇集连接方面做得非常出色。

如果你不清理它,你可能会分配一些额外的内存超过它需要的时间,但它不会让连接打开的时间超过必要的时间。

然而,最好的做法是自己清理。 即使你知道它(当前)不重要。

首先,您应该始终显式释放昂贵的资源,例如数据库连接,流等。不要依赖框架为您执行此操作。 即使它现在这样做,你也永远不知道微软是否会在未来改变它,给你带来一个你可能找不到的巨大漏洞。

您可以using块在每个操作中创建和处置上下文。

但是为了节省一些代码并遵循DRY原则,您可以通过分别覆盖OnActionExecutingOnActionExecutedContext来实例化和处理每个操作之前和之后的上下文:

 public class MyController: Controller { protected AssetManagerContext db; [HttpGet] public ActionResult Edit(int id) { MyAsset myAsset = db.Assets.Find(id); // Used and not disposed return View(myAsset); } protected override void OnActionExecuting(ActionExecutingContext db) { base.OnActionExecuting(db); db = new AssetManagerContext("ConnectionString"); } protected override void OnActionExecuted(ActionExecutedContext db) { base.OnActionExecuted(db); db.Dispose(); } }