是否需要处置entity framework上下文对象

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

简单地说: DbContext实现了IDisposable ,因此您应该在完成后立即手动处理它。

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

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

(有用的参考 。)

我认为最好的方法是在using语句中编写它

 using(var cx = new DbContext()) { //your stuff here } 

所以它被自动处理掉了

一般来说,如果某些东西实现了IDisposable ,那么当你通过时,明确处理它是一个好主意(TM)。 如果您不拥有所述对象的实现,则尤其如此; 在这种情况下你应该把它当作一个黑盒子。 另外,即使现在不一定“需要”处理它,它可能在将来。

因此,恕我直言,你是否“需要”明确处置该对象的问题是无关紧要的。 如果它要求被处置 – 由于实施IDisposable – 它应该被处置。

建议使用DBContext的方法是根本不处理它(在大多数情况下它是规则的例外),即使它是一次性对象。

问题的一个例子,第一个例子是在using语句中进行调用并对其进行评估,而第二个例子则在之后对其进行评估。 (第一个ons运行,第二个抛出错误The operation cannot be completed because the DbContext has been disposed.

 List listT; using (Model1 db = new Model1()) { listT = db.Tests.ToList(); //ToList Evaluates } foreach (var a in listT) { Console.WriteLine(a.value); } IEnumerable listT1; using (Model1 db = new Model1()) { listT1 = db.Tests; } foreach (var a in listT1) //foreach evaluates (but at wrong time) { Console.WriteLine(a.value); } 

同样的问题发生在

 IEnumerable listT1; Model1 db = new Model1(); listT1 = db.Tests; db.Dispose(); foreach (var a in listT1) //foreach evaluates (but at wrong time) { Console.WriteLine(a.value); } 

只要您不手动打开连接,只需使用即可安全使用

 IEnumerable listT1; Model1 db = new Model1(); listT1 = db.Tests; foreach (var a in listT1) //foreach evaluates (but at wrong time) { Console.WriteLine(a.value); } 

永远不要处置。 因为它会在大多数情况下照顾自己,就像它设计的那样。

现在,如果您通过强制打开连接,则上下文不会在传输完成时自动关闭它,因为它不知道何时然后您必须/应该/应该处置该对象或关闭连接并保持对象未公开。

额外的午夜阅读:

  1. http://blog.jongallant.com/2012/10/do-i-have-to-call-dispose-on-dbcontext.html#.U6WdzrGEeTw
  2. https://msdn.microsoft.com/en-us/data/jj729737.aspx