今天偶然发现的一个问题,200分,大家一起看一下

smoothwood 2004-07-23 05:16:17
大家请看下面这段程序:
Dim conn As New SqlClient.SqlConnection("server=localhost;user id=sa;password=ycm119;database=northwind;")
Dim cmd As New SqlClient.SqlCommand
Dim dtr As SqlClient.SqlDataReader
cmd.Connection = conn
cmd.CommandText = "Select * from Products"
conn.Open()
dtr = cmd.ExecuteReader
DataGrid1.DataSource = dtr
DataGrid1.DataBind()
Response.Write("isclosed=" & dtr.IsClosed)
----------------------------------
最后一句Response.Write("isclosed=" & dtr.IsClosed)输出的结果是isclosed=False ,即DataReader现在是处于打开状态。现在我把
dtr = cmd.ExecuteReader改成
dtr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
这时候Response.Write("isclosed=" & dtr.IsClosed)的输出变成isclosed=True 了,但是按照微软在MSDN上的描述:CommandBehavior.CloseConnection参数的作用是:
When the command is executed, the associated Connection object is closed when the associated DataReader object is closed.
也就是说CommandBehavior.CloseConnection参数的作用是在关闭DataReader之后,自动关闭打开的数据库连接,但是为什么在这里加上这个参数之后DataReader是否关闭的状态也受到了影响呢?
...全文
882 66 打赏 收藏 转发到动态 举报
写回复
用AI写文章
66 条回复
切换为时间正序
请发表友善的回复…
发表回复
gujianxin 2004-07-29
  • 打赏
  • 举报
回复
you also can press "space"
simonllf 2004-07-25
  • 打赏
  • 举报
回复
bu cuo
saucer 2004-07-25
  • 打赏
  • 举报
回复
select a method, go to menu Tools->Disassembler
fengyecsdn 2004-07-25
  • 打赏
  • 举报
回复
其实楼主的问题很简单,就是理解有的偏差。
CommandBehavior.CloseConnection
就是命令处理完成(包括返回完结果)关闭其使用的连接。

连接关闭后,依靠连接的DATAREADER自然也就失效,被自动释放了。


但是没有那个参数的时候,DATAREADER手动关闭以后,CONNECTION是不关闭的。
不过手动关闭CON,READER也就关闭了
smoothwood 2004-07-25
  • 打赏
  • 举报
回复
呵呵。。弄懂了,谢谢大家给出这么多的意见:)
非常感谢

最后顺便一问:思归说得那个Reflector是怎么用的:)
我怎么没有看到那些具体实现的代码
CtrlT 2004-07-25
  • 打赏
  • 举报
回复
好東東!

//-----------------------------------------------------------------//

の) -
︶ | ┣━┒ ━┻━
┟━┃ ┍╄┓ ╃┝
┝─┃ ┣╈┤ ━━━ ˋの′
我 ┗━┘ ┗┸┛ 我 × 坏 ` ˊˋ
//-----------------------------------------------------------------//
goody9807 2004-07-25
  • 打赏
  • 举报
回复
试试去
txhack 2004-07-25
  • 打赏
  • 举报
回复
这是访问MySQL数据库吗?我马上就去学,以后各位高手多多帮忙!
sunrongxa 2004-07-25
  • 打赏
  • 举报
回复
up
smoothwood 2004-07-25
  • 打赏
  • 举报
回复
多谢,多谢:)
summerboy 2004-07-24
  • 打赏
  • 举报
回复
调用datareader.close时会把连接也自动关闭了。

不调用时两者都没有关闭。

在定义datareader时使用CommandBehavior.CloseConnection后,在执行datareader后,datareader对象未关闭,但是这时数据已获得后,连接自动关闭了。


不知道说对没有。
meixiaofeng 2004-07-24
  • 打赏
  • 举报
回复
学习,up
liyufeng1983 2004-07-24
  • 打赏
  • 举报
回复
就如楼上所说,既然自动关闭了连接对象,其所占有的资源有可能已经被运行时回收,那么DataReader自然就应该也同时关闭了,因为我觉得它与连接对象应该有一种依赖的关系,运行时可能认为没有连接支持的DataReader对象也就没有了存在的必要了,也必然自动将它关闭,释放其占有的资源,等待垃圾回收。我想这也是net运行时的一种智能行为,它自动发现没有连接支持的DataReader,程序就应该不会再使用它了,就不应该再让它继续存在浪费系统资源,将它自动关闭算是做对头了。
luluso 2004-07-24
  • 打赏
  • 举报
回复
楼上的讲得不错!
auqf0dream 2004-07-24
  • 打赏
  • 举报
回复
还是放这儿吧,好看些,不用再链接了!!嘿嘿~~~~


在CSDN论坛上看到下列问题,如果把DataReader当作DataGrid的DataSource,在DataGrid.DataBind()之后,在下列两种情形下,DataReader的IsClosed的值是不同的

1.
IDataReader reader = SomeDBCommand.ExecuteReader();
DataGrid1.DataSource = reader;
DataGrid1.DataBind();

在这里,reader的IsClosed的值是false

2.
IDataReader reader = SomeDBCommand.ExecuteReader(CommandBehavior.CloseConnection);
DataGrid1.DataSource = reader;
DataGrid1.DataBind();

在这里,reader的IsClosed的值是true

结论是,如果DataReader的CommandBehavior是CloseConnection的话,DataGrid1.DataBind()在某种(也许是非直接的)方式下,调用了DataReader的Close方法。在网上找到了一个类似的讨论,但他们没有给出原因。

把DataReader作为DataGrid的DataSource时,DataReader是当作IEnumerable来看待的,从IEnumerable可以获取IEnumerator,然后可以用它的MoveNext/Current来依次获取每个记录,难道MoveNext调用了DataReader的Close方法?做了个试验

using System;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Collections;

class TestClose
{
static void Main()
{
SqlConnection conn = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=;");
SqlCommand cmd = new SqlCommand("select * from authors", conn);


conn.Open();
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
TestRead(reader);
reader.Close();

conn.Open();
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
TestMoveNext(reader);
reader.Close();

}

static void TestRead(IDataReader reader)
{
while (reader.Read());
Console.WriteLine("after Read(), reader is closed? {0}", reader.IsClosed);
}

static void TestMoveNext(IDataReader reader)
{
IEnumerator e = ((IEnumerable)reader).GetEnumerator();
while (e.MoveNext());
Console.WriteLine("after MoveNext(), reader is closed?{0}", reader.IsClosed);
}


}

输出是
after Read(), reader is closed? False
after MoveNext(), reader is closed? True

果不其然啊,用Lutz Roeder的Reflector(大力推荐!)工具看了一下.NET里SqlDataReader的实现

IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return new DbEnumerator(this, (CommandBehavior.Default != (CommandBehavior.CloseConnection & this._behavior)));
}


可见SqlDataReader的CommandBehavior确实是传进去的,再看DbEnumerator的实现

public DbEnumerator(IDataReader reader, bool closeReader)
{
if (reader == null)
{
throw ADP.ArgumentNull("reader");
}
this._reader = reader;
this.closeReader = closeReader;
}



public bool MoveNext()
{
object[] objArray1;
if (this._schemaInfo == null)
{
this.BuildSchemaInfo();
}
this._current = null;
if (this._reader.Read())
{
objArray1 = new object[this._schemaInfo.Length];
this._reader.GetValues(objArray1);
this._current = new DbDataRecord(this._schemaInfo, objArray1, this._descriptors, this._fieldNameLookup);
return true;
}
if (this.closeReader)
{
this._reader.Close();
}
return false;
}

果然, 如果DataReader的CommandBehavior是CommandBehavior.CloseConnection的话,MoveNext调用了Close方法!


dfg35_-433 2004-07-24
  • 打赏
  • 举报
回复
看了思归的解释 才知道开源的意义.....
codeangel 2004-07-24
  • 打赏
  • 举报
回复
CommandBehavior.CloseConnection 只是说明,当执行了Reader.close 关闭Reader时
Connection自动关闭!
你的那段程序代码中应有一条Reader.close 才是!
houjianxun 2004-07-24
  • 打赏
  • 举报
回复
还是思归的解释到位
qjoe0516 2004-07-24
  • 打赏
  • 举报
回复
up
auqf0dream 2004-07-24
  • 打赏
  • 举报
回复
学了不少东西呀,不过还是要关注!嘿嘿,没有高见!!!初学者
加载更多回复(46)

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧