我写了几个与实体框架一起使用的应用程序。 我曾经使用过使用子句。 使用此子句,我确信数据库连接已正确关闭。
但是,在某些情况下,我的数据库上下文对象是类的字段。它的实例化在声明中,并且没有使用子句。
我刚刚发现,在这种情况下,不会调用Dispose()方法。使用using子句,Dispose()会自动调用
所以我的问题是:如果没有在数据库上下文中调用Dispose()会发生什么?析构函数被调用,你认为数据库将被析构函数关闭吗?或者我应该在容器对象的析构函数上手动调用Dispose(),如下所示:
class MyClass
{
public MyDbContext ctx = new MyDbContext();
....
~MyClass()
{
ctx.Dispose();
}
}
由于
答案 0 :(得分:4)
您根本不得致电 Dispose
。特别explicitly
。
当您使用using
时,它是implicit Dispose()
块中的try-finally
。哪个没问题。但你不需要这样做explicitly
。
为什么?
发生separate
explicit
时Dispose
或can be missed
exception
声明earlier
。因此无法保证{{1} }} explicit
。
来自 Rowan Miller [MSFT]:
DbContext的默认行为是底层连接 需要时自动打开,否则关闭 需要更久。例如。当您执行查询并迭代查询时 结果使用“foreach”,调用IEnumerable.GetEnumerator() 会导致连接被打开,而以后则没有 更多结果可用,“foreach”将负责调用Dispose on 枚举器,它将关闭连接。以类似的方式,a 调用DbContext.SaveChanges()之前会打开连接 将更改发送到数据库并在返回之前将其关闭。
鉴于此默认行为,在许多实际案例中,它是无害的 离开上下文而不处理它只是依赖垃圾 采集。
那就是说,我们的示例代码总是有两个主要原因 使用“使用”或以其他方式处理上下文:
默认的自动打开/关闭行为相对容易覆盖:您可以控制何时打开连接并且 通过手动打开连接关闭。一旦你开始这样做 在你的代码的某些部分,然后忘记了上下文 变得有害,因为你可能会泄漏开放的连接。
- 醇>
DbContext按照推荐的模式实现IDiposable,其中包括公开虚拟保护的Dispose方法 派生类型可以覆盖,例如,如果需要聚合其他 非托管资源进入上下文的生命周期。
您可以在此处详细了解:Do I always have to call Dispose() on my DbContext objects? Nope
答案 1 :(得分:1)
如果您可以在父类上使用using
,请将其设为IDisposable:
class MyClass : IDisposable
{
public MyDbContext ctx = new MyDbContext();
....
public void Dispose()
{
ctx.Dispose();
}
}
这样,在using语句中调用父类将在退出时释放上下文。