【问题标题】:Why doesn't Dapper dot net open and close the connection itself?为什么 Dapper dot net 不打开和关闭连接本身?
【发布时间】:2015-10-13 11:51:20
【问题描述】:

Dapper 隐含地希望连接在使用时处于打开状态。为什么它不能自己打开和关闭?这不就是简单的连接管理吗?

我问是因为我和一位同事一直在反复讨论连接池在幕后发生的事情的性质,以及在多个命令之间保持连接打开或打开连接是否有任何好处并为每个命令关闭它。

【问题讨论】:

  • 此更改现已提交 btw
  • 今天早上看到了 :) 非常感谢。我喜欢您处理它的方式...如果它已经打开,请保持打开状态。如果它已关闭,请在完成后关闭它。很简单。
  • @MarcGravell 现在连接处理的语法是什么?
  • @StephenPatten 不清楚你在问什么;但在 this 问题的上下文中 - 它应该自动打开/关闭
  • @MarcGravell 一个典型的场景是将连接放在 using 语句中,打开 con,然后执行查询。这是否意味着我们现在可以跳过 con.open() 步骤?

标签: .net connection-pooling sqlconnection dapper


【解决方案1】:

Dapper 现在(并且在相当长的一段时间内)在内部处理这个问题。它只是工作™


原始(过时)答案:

你没有错。我没有注意到这种不便的原因是由于遗留原因(特别是:我们曾经专门使用 LINQ-to-SQL)我们的主要类似连接的东西是DataContext - 所以我们将 dapper 方法重新公开为DataContext 上的扩展方法。

愚蠢的是:这些方法的作用是:

using(db.Connection.EnsureOpen()) {
    db.Connection.{the dapper method}
}

这里 EnsureOpen 是一个厚颜无耻的方法:

  • 如果连接打开,则返回 null
  • 否则,它会打开连接,并返回一个 IDisposable 令牌,该令牌会在完成后关闭连接

所以:我们显然完全地感受到了你的痛苦,但我们在更上一层实施了它。

请将此记录为功能请求。我们拥有所有代码(尽管我需要稍微调整它以适应非缓冲数据的“阅读器”)- 绝对没有理由 dapper 不能拥有它的所有权。

【讨论】:

  • @Marc - 现在我们使用工作单元模式来处理连接/TransactionScope。如果我们在 Query 扩展方法中处理 IDbConnection(有效地消除了在 UnitOfWork 中处理连接状态的需要),这不会对多个后续查询的性能产生负面影响吗?
  • @Chris 关键是让它双向工作。如果您想要一个跨越多个操作的连接,那么请确保:为您的工作单元打开它(实际上,通常整个网络请求就是一个工作单元)。如果您希望它在内部处理它,那么这应该是可以支持的。它不会停止为您的意图工作。我非常了解性能优化需求:)
  • @Michael 哇,github 上的那句话已经完全过时了。如果 Dapper 检测到连接未打开,它确实会(一段时间)根据需要打开/关闭。
  • @MarcGravell 感谢您的确认!您会建议我们从我们的代码中手动打开/关闭连接(使用“使用”块)吗?或者,如果我们让 Dapper 负责连接生命周期,这样我们可以从连接池中获得优势,会更好吗?谢谢!
  • @Michael 好吧,从技术上讲,打开/关闭与处置不同。如果您只打算打开/关闭单个呼叫,您不妨让 dapper 来做。如果您以更宽的粒度打开/关闭(例如,每个请求),最好让您的代码执行此操作并将打开的连接传递给 dapper。
【解决方案2】:

我必须在这里添加一个相反的答案,或者至少建议 Dapper 可能会以不同的方式处理连接,即使只是在某些情况下。我刚刚反映了 Dapper.SqlMapper 并且在 ExecuteCommand 方法中进行了检查(由 Execute 调用(在公共 api 上))以检查连接是否关闭,然后打开它,如果不是。

我的同事在进行代码审查时强调了我在通过 dapper 调用数据库之前没有明确调用 connection.open。这没有被采纳,因为我的集成测试都是绿色的,在运行时一切都是笨拙的。所以我们深入研究了 Dapper 代码。有人可能会争辩说,为了明确性而调用 open 更好,但相反,有些人可能会争辩说代码越少越好。

【讨论】:

  • 刚刚看到 Marc 在上面关于自动管理连接的评论。很抱歉陈述了一些人已经知道的内容,但是当我第一次浏览答案时并没有立即发现。
【解决方案3】:

我相信 Dapper 不会管理您的连接,因为它超出了它作为 ORM 映射器的职责范围。 Dapper 不知道您以后是否会重用相同的连接 - 这就是它接受连接作为参数之一的原因。这同样适用于事务 - 应该管理事务的是应用程序,而不是 ORM 映射器。

编写自己的扩展方法来管理连接是微不足道的。

【讨论】:

  • 我不认为这超出了它的职责范围。它正在访问数据库,为什么它在准备运行命令时无法打开连接并在完成后关闭它?这可能是额外的 5 行代码。
  • @smdrager 由于缓冲与非缓冲的复杂性,可能比 5 行多几行,但我不能不同意你的其余部分。
  • @smdrager 打开连接可能没问题,但您不能在事务中间关闭连接。不知道为什么 Query 方法打开连接,但其他一些方法不这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
  • 2012-02-28
  • 1970-01-01
  • 2015-12-11
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
相关资源
最近更新 更多