我需要在LINQ查询后强制执行Dispose吗?

时间:2015-02-19 03:39:54

标签: c# entity-framework database-connection idisposable

我的DBA说有太多的连接打开了,他认为这是我在.net中的代码让他们打开。

我首先使用LINQ查询和EF代码。

示例方法:

 public List<Stuff> GetStuff()
 {
      var db = new DBContext();

      var results =  db.stuff.toList();

      return results;
 }

完成后我是否需要处理db var?我的理解是我不需要在EF和LINQ中。请指向我关于管理代码中的连接或LINQ / EF和数据库连接的最佳实践的Microsoft文档

更新

我添加了

db.Connection.Close();
db.Dispose();

我仍然在执行两行后看到SQL中的开放连接。当我强迫它关闭时,它有什么理由不能关闭吗?

6 个答案:

答案 0 :(得分:25)

你应该听你的DBA!是的,使用using。不要不必要地打开连接。您应该连接,与db一起开展业务,并关闭该连接,将其释放以用于另一个进程。在高容量系统中尤其如此。

编辑。让我用这里的经验进一步解释。在小批量处理中,它可能不是一个问题,但是当它明确地实现using时,不明确地处理某些东西或不将它包装在IDisposable中是一个坏习惯。

在大批量情况下,这只是要求灾难。 Sql server将为每个应用程序分配这么多连接(可以在连接字符串中指定)。如果没有及时关闭,进程将花费时间等待连接释放。在某些情况下,这通常会导致超时或死锁。

当然,您可以调整Sql server connection mgmt等,但每次调整设置时,您都会做出妥协。您必须考虑运行备份,运行其他作业等。这就是明智的开发人员会听取DBA警告的原因。它并不总是关于代码...

答案 1 :(得分:12)

我刚问了这个same question over on Programmers.SE。罗伯特哈维给出了一个很好的答案。

  

通常,您不需要在实体框架数据上下文中使用Using语句。懒惰的收藏是其中一个原因。

我鼓励您阅读关于Programmers.SE的完整答案以及Robert在答案中提供的链接。

答案 2 :(得分:5)

据我所知,实体框架默认使用connection pooling来减少每次创建新连接的开销。 关闭应用程序时连接是否已关闭?

如果是这样,您可以尝试减少连接字符串中的最大池大小或完全禁用连接池。 有关连接字符串中可能选项的参考,请参阅here

答案 3 :(得分:4)

默认情况下,DbContext会自动为您管理连接。因此,您不必显式调用Dispose。

关于此主题的博客文章:Link

但我相信,如果您处理大量请求,不进行处置可能会导致性能问题。您应该添加一个using语句,以查看它是否会导致您的案例出现问题。

答案 4 :(得分:1)

是的,如果您的方法定义了工作单元;不,如果更原始的东西。 (P.S.代码中的某个地方应该定义一个工作单元,那个东西应该包含在using (var context = new DbContext()) {}或等价物中。)

如果你属于思想流派,你的DbContext 是你的工作单位,那么你总是用{{1}包裹那个坏孩子} block:先前在上下文生命周期中提取的数据的本地缓存以及using方法充当一种轻量级事务,而您的SaveChanges(不调用Dispose)是您的回滚(而你的SaveChanges是你的提交。)

答案 5 :(得分:0)

检查一下,这是关于如何使用IDisposable对象的标准协议。 https://msdn.microsoft.com/en-us/library/yh598w02.aspx

它说:

“通常,当您使用IDisposable对象时,您应该在using语句中声明并实例化它。”

由于他们可以访问非托管资源,因此您应该始终考虑使用“使用”语句。