EntityFramework上下文处理

Bob*_*421 4 entity-framework

我写了一些与实体框架一起使用的应用程序。我曾经使用过using子句。使用此子句,我确定数据库连接已正确关闭。

但是,在某些情况下,我的数据库上下文对象是类的字段。它的实例化在声明中,并且没有using子句。

我刚刚发现,在这种情况下,不会调用Dispose()方法。使用using子句时,会自动调用Dispose()

所以我的问题是:如果未在数据库上下文中调用Dispose()会发生什么?析构函数被称为,所以您认为数据库将被析构函数关闭吗?还是我应该像这样在容器对象的析构函数上手动调用Dispose():

class MyClass
{
    public MyDbContext ctx = new MyDbContext();

    ....

    ~MyClass()
    {
         ctx.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Sam*_*ath 5

绝对不能打电话 Dispose。特别是explicitly

使用时, using它是implicit Dispose()一个try-finally障碍。很好explicitly。但是你不需要做。

为什么呢

一个separateexplicit Dispose语句can be missedexception发生earlier。所以这是毫无保障explicit Dispose

这是来自Rowan Miller [MSFT]的:

DbContext的默认行为是在需要时自动打开基础连接,并在不再需要时关闭基础连接。例如,当您执行查询并使用“ foreach”遍历查询结果时,对IEnumerable.GetEnumerator()的调用将导致连接打开,而当以后没有更多结果可用时,“ foreach”将负责调用放在枚举器上,它将关闭连接。以类似的方式,对DbContext.SaveChanges()的调用将在将更改发送到数据库之前打开连接,并在返回之前将其关闭。

考虑到这种默认行为,在许多实际情况下,无需丢弃上下文而仅依靠垃圾回收就可以保留上下文。

也就是说,我们的示例代码倾向于始终使用“使用”或以其他方式处置上下文的两个主要原因是:

  1. 默认的自动打开/关闭行为相对容易覆盖:您可以通过手动打开连接来控制何时打开和关闭连接。一旦在代码的某些部分开始执行此操作,然后忘记丢弃上下文就变得有害,因为您可能会泄漏打开的连接。

  2. DbContext按照建议的模式实现IDiposable,该模式包括公开一个虚拟的受保护的Dispose方法,例如,如果需要将其他非托管资源聚合到上下文的生存期中,派生类型可以覆盖该方法。

您可以在此处了解更多信息:我是否总是必须在DbContext对象上调用Dispose()?不

使用实体框架以正确的方式管理DbContext