关于.net:SqlCommand.Dispose是否关闭连接?

关于.net:SqlCommand.Dispose是否关闭连接?

Does SqlCommand.Dispose close the connection?

我可以有效地使用这种方法吗?

1
2
3
4
5
6
using(SqlCommand cmd = new SqlCommand("GetSomething", new SqlConnection(Config.ConnectionString))
{
    cmd.Connection.Open();
    // set up parameters and CommandType to StoredProcedure etc. etc.
    cmd.ExecuteNonQuery();
}

我的担心是:SqlCommand的Dispose方法(退出using块时会调用)是否关闭基础SqlConnection对象?


否,处置SqlCommand不会影响连接。更好的方法是将SqlConnection也包装在using块中:

1
2
3
4
5
6
7
8
using (SqlConnection conn = new SqlConnection(connstring))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand(cmdstring, conn))
    {
        cmd.ExecuteNonQuery();
    }
}

否则,由于使用了连接的命令已被处理(也许正是您想要的?),因此该连接不变。但是请记住,连接应该
也要被处置,并且处置可能比命令更重要。

编辑:

我刚刚测试了这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SqlConnection conn = new SqlConnection(connstring);
conn.Open();

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 1", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 2", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

conn.Dispose();

退出using块时,将处理第一个命令。该连接仍处于打开状态,对于第二个命令来说是好的。

因此,处置该命令绝对不会处置其正在使用的连接。


SqlCommand.Dispose是不够的,因为许多SqlCommand可以(重新)使用相同的SqlConnection。将重点放在SqlConnection上。


许多地方都弄错了,甚至MS自己的文档。只需记住-在数据库世界中,几乎所有内容都由不受管理的资源支持,因此几乎所有内容都实现IDisposable。除非编译器另行通知,否则假定类确实起作用。
在使用中包装命令。将您的连接包装在使用中。在DbProvider上创建连接(从DbProviderFactories.GetFactory获得连接),并在连接上关闭命令,以便在更改基础数据库时,只需更改对DBPF.GetFactory的调用。
因此,您的代码最终应该看起来不错且对称:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var provider = DbProviderFactories.GetFactory("System.Data.SqlClient");// Or MS.Data.SqlClient
using (var connection = provider.CreateConnection())
{
    connection.ConnectionString ="...";
    using (var command = connection.CreateCommand())
    {
        command.CommandText ="...";
        connection.Open();

        using (var reader = command.ExecuteReader())
        {
...
        }
    }
}

我使用这种模式。我的应用程序中某处有此私有方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void DisposeCommand(SqlCommand cmd)
{
    try
    {
        if (cmd != null)
        {
            if (cmd.Connection != null)
            {
                cmd.Connection.Close();
                cmd.Connection.Dispose();
            }
            cmd.Dispose();
        }
    }
    catch { } //don't blow up
}

然后,我总是在try块中创建SQL命令和连接(但不包装在using块中),并且始终将finally块设置为:

1
2
3
4
    finally
    {
        DisposeCommand(cmd);
    }

在这种情况下,连接对象是命令对象的属性,这使using块变得笨拙-但是此模式可以完成工作而不会使您的代码混乱。


推荐阅读

    linux命令连接光驱?

    linux命令连接光驱?,系统,位置,设备,数据,电脑,服务,资料,盘中,智能,管理,Lin

    linux跳板机连接命令?

    linux跳板机连接命令?,地址,服务,密码,工具,中国,网络,位置,系统,电脑,在线,

    linux命令行拨号连接?

    linux命令行拨号连接?,系统,网络,软件,手机,服务,密码,地址,名称,电话号码,

    linux命令连接光驱?

    linux命令连接光驱?,系统,位置,设备,数据,电脑,服务,资料,盘中,智能,管理,Lin

    linux命令逻辑连接符?

    linux命令逻辑连接符?,系统,网络,名字,环境,信息,名称,设备,发行,位置,较大,L

    linux跳板机连接命令?

    linux跳板机连接命令?,地址,服务,密码,工具,中国,网络,位置,系统,电脑,在线,

    linux命令关闭视图?

    linux命令关闭视图?,系统,状态,管理,百分比,信息,情况,基础,软件,观察,首次,

    linux命令关闭防火墙?

    linux命令关闭防火墙?,服务,软件,系统,信息,设备,公共,防火墙,命令,之间,内

    linux连接外网命令?

    linux连接外网命令?,网络,系统,工具,情况,软件,信息,地址,代理,地方,数据,请

    linux关闭防火前命令?

    linux关闭防火前命令?,系统,服务,软件,信息,管理,防火墙,命令,环境,公共,设

    linux关闭蓝牙命令?

    linux关闭蓝牙命令?,服务,系统,状态,工作,发行,名字,地址,信息,软件,情况,lin

    linux休眠关闭命令?

    linux休眠关闭命令?,系统,设备,信息,状态,代码,时间,传播,地址,控制权,投入,l

    linux关闭子进程命令?

    linux关闭子进程命令?,系统,进程,名称,软件,管理,传播,命令,信息,状态,数字,l

    关闭启动linux的命令?

    关闭启动linux的命令?,服务,系统,命令,代码,手机,软件,密码,管理,信息,状态,l

    linux关闭se命令?

    linux关闭se命令?,状态,系统,手机,工具,命令,标准,文件,提示符,方法,防火墙,

    linux命令连接ip?

    linux命令连接ip?,地址,系统,网络,工作,信息,命令,密码,名称,设备,服务,linux

    linux命令连接网址?

    linux命令连接网址?,网址,系统,地址,服务,传播,数据,命令,名字,环境,网站,如

    linux命令关闭机器?

    linux命令关闭机器?,系统,工作,银河,命令,设备,标准,用户,方式,终端,麒麟,lin

    linux连接多条命令?

    linux连接多条命令?,工具,情况,命令,分行,服务,地址,连续,终端,窗口,主机,lin

    linux有线网连接命令?

    linux有线网连接命令?,系统,网络,软件,电脑,密码,地址,信息,虚拟机,终端,命