调用SqlCommand或SqlDataAdapter的Dispose方法,是否会关闭绑定的SqlConnection?(转载)
1. Does SqlCommand.Dispose close the connection?
问
Can I use this approach efficiently?
using(SqlCommand cmd = new SqlCommand("GetSomething", new SqlConnection(Config.ConnectionString))
{
cmd.Connection.Open();
// set up parameters and CommandType to StoredProcedure etc. etc.
cmd.ExecuteNonQuery();
}
My concern is : Will the Dispose method of the SqlCommand (which is called when exiting the using block) close the underlying SqlConnection object or not?
答
No, Disposing of the SqlCommand will not effect the Connection. A better approach would be to also wrap the SqlConnection in a using block as well:
using (SqlConnection conn = new SqlConnection(connstring))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(cmdstring, conn))
{
cmd.ExecuteNonQuery();
}
}
Otherwise, the Connection is unchanged by the fact that a Command that was using it was disposed (maybe that is what you want?). But keep in mind, that a Connection should be disposed of as well, and likely more important to dispose of than a command.
EDIT:
I just tested this:
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();
The first command was disposed when the using block was exited. The connection was still open and good for the second command.
So, disposing of the command definitely does not dispose of the connection it was using.
2. Does SqlDataAdapter.Dispose actually Close an associated SqlConnection?
问
Does anyone know if the SqlDataAdapter.Dispose method actually closes or disposes any SqlConnections? I loaded up Reflector and I see that SqlDataAdapter inherits from DbDataAdapter. If I disassemble and look at the dispose method in that class, there appears to be no disposal of any SqlConnections. I suppose I could write a test for this, but I figured I would ask to see if anyone had any insight on this.
答
The first thing to be aware of is that the DataAdapter does manage and close your connection in some circumstances. For example, if you're using a DataAdapter you're probably operating on DataTables/DataSets using the .Fill() and .Update() functions.
From the .Fill() docs:
The connection object associated with the SELECT statement must be valid, but it does not need to be open. If the connection is closed before Fill is called, it is opened to retrieve data, then closed. If the connection is open before Fill is called, it remains open.
The .Update() docs don't mention anything about the connection at all, so I would expect to need to manage it manually.
Now you asked specifically about the Dispose() method. Like Update, the Dispose() docs don't specifically mention the connection, so I would expect to need to close it manually.
Finally, we can improve on Bob King's code slightly like this:
Using conn as New SqlConnection(""), _
adapter as New SqlDataAdapter() With {.Connection = conn}
'Do stuff
End Using
Or in C#:
using (SqlConnection conn = new SqlConnection(""))
using (SqlDataAdapter adapter = new SqlDataAdapter() {Connection = conn})
{
// Do stuff
}
Not 100% I got the initialize syntax for the adapter right, but I typed it directly into the reply window. I'll fix it later if needed.
3. Does SqlDataAdapter close the SqlConnection after Fill() function?
问
Does SqlDataAdapter close the SqlConnection after the Fill() function or do I need close it myself?
string cnStr = @"Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
cn = new SqlConnection(cnStr);
SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn);
SqlDataAdapter adapter = new SqlDataAdapter(cmd); DataSet ds = new DataSet();
adapter.Fill(ds); cn.Close() // ???????? Console.WriteLine(ds.Tables[].Rows.Count);
Console.WriteLine(cn.State);
答
In your current usage, it will close for you:
If the IDbConnection is closed before Fill is called, it is opened to retrieve data and then closed. If the connection is open before Fill is called, it remains open.
I think it's always better to explicitly cater for it yourself with a using statement:
using (SqlConnection conn = new SqlConnection(""))
{
conn.Open();
// Do Stuff.
} // Closes here on dispose.
This is often more readable and doesn't rely on people understanding the inner workings of SqlDataAdapter.Fill, just the using statement and connections.
However, if you know the connection is closed before the adapter uses it (as in, you've just created the connection) and it's not used for anything else, your code is perfectly safe and valid.
Personally, I'd write something like this:
string cnStr = "Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
DataSet ds = new DataSet(); using (SqlConnection cn = new SqlConnection(cnStr))
{
using (SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn))
{
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
cn.Open();
adapter.Fill(ds);
}
}
}
调用SqlCommand或SqlDataAdapter的Dispose方法,是否会关闭绑定的SqlConnection?(转载)的更多相关文章
- 强制回收和IDisposable.Dispose方法
如果某对象的 Dispose 方法被调用一次以上,则该对象必须忽略第一次调用后的所有调用. 如果对象的 Dispose 方法被多次调用,该对象一定不要引发异常. 除Dispose 之外的实例方法在资源 ...
- 编写高质量代码改善C#程序的157个建议——建议48:Dispose方法应允许被多次调用
建议48:Dispose方法应允许被多次调用 一个类型的Dispose方法应该允许被多次调用而不抛出异常.鉴于此,类型内部维护了一个私有的bool变量disposed,如下: private bool ...
- SqlCommand和SqlDataAdapter的区别
SqlDataAdapter对象 一.特点介绍1.表示用于填充 DataSet 和更新 SQL Server 数据库的一组数据命令和一个数据库连接.2.在SqlDataAdapter和DataSet之 ...
- C# SqlCommand和SqlDataAdapter的区别
SqlCommand和SqlDataAdapter的区别 SqlCommand对应DateReader SqlDataAdapter对应DataSet SqlCommand的执行效率比较高,但 ...
- JS魔法堂:定义页面的Dispose方法——[before]unload事件启示录
前言 最近实施的同事报障,说用户审批流程后直接关闭浏览器,操作十余次后系统就报用户会话数超过上限,咨询4A同事后得知登陆后需要显式调用登出API才能清理4A端,否则必然会超出会话上限. 即使在页面 ...
- 实现 Dispose 方法
实现 Dispose 方法 MSDN 类型的 Dispose 方法应释放它拥有的所有资源.它还应该通过调用其父类型的 Dispose 方法释放其基类型拥有的所有资源.该父类型的 Dispose 方法应 ...
- 定义页面的Dispose方法:[before]unload事件启示录
前言 最近实施的同事报障,说用户审批流程后直接关闭浏览器,操作十余次后系统就报用户会话数超过上限,咨询4A同事后得知登陆后需要显式调用登出API才能清理4A端,否则必然会超出会话上限. 即使在页面上增 ...
- 是否需要手动执行DataContext的Dispose方法?
我们知道DataContext实现了IDisposable接口.在C#中,凡是实现了IDisposable接口的类,都推荐的使用using语句.如下: using (DataContext db = ...
- 析构函数和Dispose方法的区别
1. 析构函数(Finalize)只能释放非托管资源, 它是由GC调用. 2. Dispose方法可以释放托管资源和非托管资源,它是由用户手动调用的. 在Dispose()中调用 GC.Suppres ...
随机推荐
- SQLserver创建用户和给用户权限(学)
数据库基础知识:http://blog.csdn.net/u014600432/article/details/39645701 在SQL Server中创建用户角色及授权(使用SQL语句):http ...
- Spring源码解析系列汇总
相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...
- Javase之多线程(1)
多线程(1) 多线程的概述 了解多线程之前需要先了解线程,而线程依赖于进程而存在,所以先了解进程. 什么是进程 进程就是正在运行的程序.是系统进行资源分配和调用的独立单位.每一个进程都有它自己的内存空 ...
- 多线程CGD调度组原理
我们常用的GCD调度组方式 //GCD常用调度组写法 -(void)demo1{ //创建调度组和队列 dispatch_group_t group = dispatch_group_create() ...
- 解决iOS地图持续定位耗电问题
地图位置刷新的代理didUpdateLocations会持续调用,手机非常耗电 但是在实际开发中,有一些APP确实需要用到持续定位的功能,比如:运动类, 导航类, 天气类等等 如何进行持续定位呢?保证 ...
- [20190913]完善vim的bccacl插件2.txt
[20190913]完善vim的bccacl插件2.txt --//继续完善vim的bccacl插件.--//\bc 计算也可以直接使用 \bb 操作,这样操作更快一些.--//增加直接写好算式计算的 ...
- 基于TCP连接的socket套接字编程
基于TCP协议的套接字编程(简单) 服务端 import socket server = socket.socket() server.bind( ('127.0.0.1', 9999) ) serv ...
- 29.Java基础_接口
接口的成员特点
- Jmeter(二)响应内容乱码解决办法
Jmeter请求编码设置为UTF-8,响应内容依然乱码,可在Jmeter安装路径bin\jmeter.properties中设置默认编码为UTF-8,于是问题得以解决:
- Linux学习(一)简介
Linux 简介 Linux 内核最初只是由芬兰人林纳斯·托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的. Linux 是一套免费使用和自由传播的类 Unix 操作系统 ...