使用带有connection.open的语句

Joh*_*ski 15 c# ado.net

我正在查看一些代码并与同事讨论.

特别是一段看起来像这样的代码.

    [Test]
    public void TestNormalWay()
    {
        using(var cn = GetConnection())
        {
            cn.Open();
            // do stuff
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题出现了:

"为什么不将cn.Open移动到GetConnection方法中."

我说如果"打开"抛出一个异常处理就不会被调用.他的回答是

"那么什么.连接没有打开,为什么需要关闭(或处理)?"

对我来说,这只是一个不想知道我是否需要处理/关闭的问题所以我会重复cn.Open代码而不是将其移动到共享函数中.

它很有趣......所以我在SQL Server连接池(ADO.NET)上做了一些阅读

对我来说,目前尚不清楚是否存在调用cn.Open并抛出异常需要调用dispose的场景.

所以在下面的例子中,"TestNormalWay"和"WhyNotDoItThisWay"之间是否存在任何差异

    protected static DbConnection GetConnection()
    {
        DbConnection cn = new SqlConnection("SomeConnecitonstring... ");
        return cn; 
    }

    protected static DbConnection GetConnectionDangerousVersion()
    {
        DbConnection cn = new SqlConnection("SomeConnecitonstring... ");
        cn.Open();  // this will throw.. .dispose not called
        return cn; 
    }

    [Test]
    public void TestNormalWay()
    {
        using(var cn = GetConnection())
        {
            cn.Open();
            // do stuff
        }
    }

    [Test]
    public void WhyNotDoItThisWay()
    {
        using(var cn = GetConnectionDangerousVersion())
        {
            // do stuff
        }
    }
Run Code Online (Sandbox Code Playgroud)

Jam*_*unt 7

您编写代码的方式总是希望在创建连接后立即打开连接,因此没有任何区别.

但是,您可以多次打开和关闭连接,并且在设计的代码中有很大的不同.

我可能想编写一些代码,其中我有一个长时间运行的例程,它接受一个连接对象并随着时间的推移打开并关闭它.例程可能不关心连接对象是如何创建的.因此,将创建连接的行为与打开和关闭它的行为分开是有利的.

关于资源管理问题,我同意这不是问题.创建SQL连接对象本身并不会锁定任何资源,而是打开它获取池化连接的行为.如果open返回异常,我认为假设没有打开连接是合理的.


小智 7

我倾向于只返回你的方法中SqlConnection没有调用的实例Open().如果需要,应该这样做.您的实用程序功能不需要它.

其中一个原因是,有些对象需要a SqlConnection,但不一定需要打开它们.例如,a SqlDataAdapter取a SqlConnection,并在其自身内处理它的打开和关闭.当然,你可以在传递之前打开一个连接,但是你必须明确地关闭它.

退一步后,调用代码应该负责处理与之完全相关的问题SqlConnection.