C# 记住.net中的SQL连接状态?

C# 记住.net中的SQL连接状态?,c#,.net,connection-pooling,dapper,sqlconnection,C#,.net,Connection Pooling,Dapper,Sqlconnection,除此之外还有一个古老的已知事实,即connection.Close()与connection.Dispose()是相同的-除了在已处理的连接上运行Close()会在关闭的连接上运行Close()时引发异常-这没问题-我仍然有一个问题: 假设连接池处于启用状态(默认)-为什么记住连接的状态很重要 我读到过这样一篇文章:避免打开和关闭连接可以节省性能 这似乎合乎逻辑,但问题是连接从未真正关闭过!它只标记为关闭 即使我在using作用域下使用它,dispose也会关闭连接并将其放回池中 即使我愿意,我

除此之外还有一个古老的已知事实,即
connection.Close()
connection.Dispose()
是相同的-除了在已处理的连接上运行
Close()
会在关闭的连接上运行
Close()
时引发异常-这没问题-我仍然有一个问题:

假设连接池处于启用状态(默认)-为什么记住连接的状态很重要

我读到过这样一篇文章:避免打开和关闭连接可以节省性能

这似乎合乎逻辑,但问题是连接从未真正关闭过!它只标记为关闭

即使我在
using
作用域下使用它,dispose也会关闭连接并将其放回池中

即使我愿意,我也不能让它打开(因为我希望其他人使用它)。所以我不得不关闭/处理它

这也实现了此行为:

public static async Task<IEnumerable<T>> QueryAsync<T>(this...)
        {
         //...
            bool wasClosed = cnn.State == ConnectionState.Closed;
            using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
            {
                try
                {
                    if (wasClosed) await ((DbConnection)cnn).OpenAsync()...
                  //...
                }
                finally
                {
                    if (wasClosed) cnn.Close();
                }
            }
        }
公共静态异步任务查询同步(此…)
{
//...
bool wascolled=cnn.State==ConnectionState.Closed;
使用(var cmd=(DbCommand)command.SetupCommand(cnn,info.ParamReader))
{
尝试
{
if(wasClosed)wait((DbConnection)cnn).OpenAsync()。。。
//...
}
最后
{
如果(wascolled)cnn.Close();
}
}
}
如你所见,“记忆”在这里实现

注意,我已经问过Marc一个相关的话题,那就是为什么在dapper示例中,他同时使用
GetClosedConnection
GetOpenConnection
,我得到的答案是,dapper可以处理这两种情况。然而,当前的问题是,为什么要重新设置连接状态

问题:

看着简洁的代码,它似乎记住了状态,并在操作后重新设置了状态。(我也从旧的sqldataadapter类中知道这种行为)

问题是——为什么?如果我有一个关闭的连接-然后,我需要打开它。伟大的但我为什么要按条件关闭它呢?为什么不总是关上它?这不会影响性能,因为连接实际上并没有关闭——它只返回到池中

另一方面,如果我有一个开放的连接,那么我会做工作并保持它开放(嗯??)


正如你可能看到的,我遗漏了一些东西。有人能解释一下吗?

如果您正在编写一个库函数,其中消费者可以向您传递一个连接对象(无论什么味道),那么最安全的做法是尊重该连接:

  • 如果向您传递了一个打开的连接对象,请不要对其进行任何假设,当然也不要在您完成工作后关闭它—您不知道您的消费者对它做了什么或将要做什么
  • 如果您被传递了一个封闭连接对象,那么您最好在尝试使用它之前打开它,并且您应该在完成后关闭它-您知道您的消费者不能通过封闭连接打开事务,例如
如果您的代码创建了一个连接对象,那么我始终建议您使用语句将该创建放在一个
中,这样在您完成创建时它将始终关闭

因此,我能想到的唯一一件事是仔细考虑编写函数,并确定消费者向您传递连接对象是否有意义-如果您的工作应该始终单独执行,例如,请求一个连接字符串,并让您的代码完全控制连接,这会更有意义

为什么不总是关上它

用户可以在该连接上进行大量工作。它可能与一个事务关联(关闭将使其孤立)。它可以有临时表(关闭会破坏它们),也可以有其他连接保留状态(
SET
options、模拟等)

在这里关闭一个连接(如果它最初是打开的)将是一件不寻常的、意想不到的事情,并且会产生多种恶劣的副作用