是否需要处置实体框架上下文对象

Abh*_*nay 15 .net c# wcf entity-framework

我们在WCF服务方法中使用实体框架与数据库进行通信,最近我们在服务代码上运行代码审查工具.像往常一样,我们通过工具获得了许多审核提案,许多评论意见建议处置实体框架上下文对象.所以,我的问题是,如果我在方法中使用实体框架上下文对象,一旦我退出该方法,GC不会清理上下文对象?我们需要显式处理上下文对象吗?

Dan*_*zey 28

简单地说:DbContext工具IDisposable,因此你应该在完成后立即手动处理它.

不需要处理它,因为GC最终会收集它,但GC不是确定性的:你永远不知道什么时候会"最终".在它被处理之前,它将保留未使用的资源 - 例如,它可能仍然具有开放的数据库连接.除非您手动处理,否则在GC运行之前不会释放这些资源.根据具体细节,您可能会发现您不必要地阻止了网络资源,文件访问,并且您肯定会保留比您需要的更多内存.

还有一个潜在的打击:当你手动处理一个对象时,GC通常不需要在该对象上调用Finalizer(如果有的话).如果让GC自动处理带有Finalizer的对象,它会将对象放在Finalizer Queue中 - 并自动将对象提升到下一代GC生成.这意味着具有终结器的对象将始终以比GCed之前所需的数量级更长的数量级挂起(因为不太频繁地收集连续的GC生成).DBContext由于底层数据库连接将是非托管代码,因此可能属于此类别.

(有用的参考.)

  • 是关于GC和IDisposable目的的问题,还是关于DbContext的具体问题? (6认同)
  • 实际上看起来你没有必要处理DBcontext(按设计)http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext.html#.U6WdzrGEeTw (5认同)
  • 这取决于OP和那些赞成这个答案的人.我在这里没有看到任何特定于DbContext的内容.没有解释应该发布什么样的资源. (3认同)

Ste*_*hev 10

我认为最好的方法是在using语句中对其进行编码

using(var cx = new DbContext())
{
  //your stuff here
}
Run Code Online (Sandbox Code Playgroud)

所以它得到了自动处理

  • 如果我们使用这种方法,我们如何模拟 DBContext 来编写单元测试? (2认同)
  • 如果我想在全类范围内使用上下文,该怎么办?(在构造函数中创建它 - 如何以及在哪里关闭它?) (2认同)