【献给初学者】
主要讨论以下几个问题(为说明方便,以我以OleDb和Access为例,sqlClient和sql类似,并以类名作为实例名叙述)
1)使用OleDbDataAdapter.Fill方法时如果OleDbConnection连接未打开是会自动打开的,那么有必要提前开启连接吗?
2)自动打开连接后,连接就保持开启状态吗?
3)假如连着同一个数据库的两个连接OleDbConnection1和OleDbConnection2都提前打开,在OleDbConnection1中使用OleDbCommand1.ExecuteNonQuery()创建了一个数据表table1,然后紧接着用
OleDbCommand2和OleDbDataAdapter2读取table1的数据,会跳出如下错误:
【Microsoft Jet 数据库引擎找不到输入表或查询 'table1'。 确定它是否存在,以及它的名称的拼写是否正确。】
此时,你若打开Access文件,会发现table1是存在的,为什么?(我不知道sqlserver或其它数据库是否有这个问题)解答:
1)有必要。在C#编程的时候,我们知道一般的数学函数、逻辑函数等哪怕看着上百上千行,但对现在的CPU来说可能就是微秒甚至往往是纳秒级别的事情,相比之下打开和关闭数据库的耗时就是天文数字了。
比如我的CPU是奔腾双核2.7GHZ,xp系统,执行下面代码看执行时间:OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; data source=ZOYAN.mdb");
System.Diagnostics.Stopwatch watcher = new System.Diagnostics.Stopwatch();//该类用于测量运行时间
watcher.Start();
con.Open();
watcher.Stop();
Console.WriteLine("conOpenTime:" + watcher.Elapsed.TotalMilliseconds.ToString());
第一次运行的执行时间都在48ms左右,类似的关闭连接的执行时间也都在40ms左右。
如果你觉的50ms左右的时间也可以忽略,也可以这么说,但如果引入第二个疑问,这个时间就可能变的很长。2)如果在使用OleDbDataAdapter.Fill之前连接是关闭的,那么会先自动打开连接,然后在Fill的末尾又会自动关闭连接。但如果之前连接就是开着的,那么事后连接也不会自动关闭,会保持开启状态。
于是初学者可能就会出现这样的错误:从不提前开启连接,在一个动作中多次使用OleDbDataAdapter.Fill,我们假如有5次。由于每次执行OleDbDataAdapter.Fill都会开启一次、关闭一次连接,共耗时接近100ms,那么5次就接近500ms,足够肉眼察觉出来,但粗看代码又不明所以,甚至怀疑是查询数据库有五次太多了?以上两个问题放在一起,就显示出为什么要尽量提前手动打开连接的原因了,尤其是在短时间内多次查询数据库的时候,而不要不明就里的依赖连接的自动开启。3)该问题也可以转换为"与数据库的连接一直打开可以吗?"
如果总共就一个连接,我觉的直到软件退出才关闭,都是没有太大的关系的,但我们往往要开多个连接,那么此时就可能产生异常了。
   我觉的这个问题可以这么理解,两个提前打开的连接OleDbConnection1和OleDbConnection2,在他们打开的时候是没有table1的。就好像我们通过打开文件的方式访问数据库一样,如果同时通过软件在数据库中新建了一个表,那么你手动打开的数据库是不是需要"刷新"一下才能看到?那么这个两个连接的道理也类似,你在OleDbConnection1中新建了表格,按理来说在同样是早早就开着的OleDbConnec2中也是需要"刷新一下"才能看到的。事实上也如此,OleDbConnection2会自动刷新,但这需要时间,如果向上述代码那样,理解执行查询的话,刷新还没开始或者还没完成,就会跳出找不到table1的错误。
   因此多个连接一直开着也是很不好的习惯,当然这个实例作为论据略显不足,因为创建数据表后立马查询理应放在一个连接中就好了,放在两个连接中本身思路就有问题。但不论如何,我想说的是,连接的开启与关闭看似细枝末节,但对初学者来说也是有很多值得注意的地方