SqlConnection SqlCommand SqlDataReader IDisposable
SqlConnection
, SqlCommand
和SqlDataReader
都实现了IDisposable
接口。 我阅读了最佳做法,始终将IDisposables
换成using
块。
所以,查询数据的常见情况看起来像这样(当然,在更大的背景下,像linq2sql这样的映射工具将是合适的,但是假设我们想在这里使用这种方法):
using (SqlConnection cn = new SqlConnection("myConnectionstring")) { using (SqlCommand cm = new SqlCommand("myQuery", cn)) { // maybe add sql parameters using (SqlDataReader reader = cm.ExecuteReader()) { // read values from reader object return myReadValues; } } }
这是正确的方式还是可以被认为是矫枉过正? 我对using
块的这种嵌套级别有些不确定,但是当然我想要正确的做法。 谢谢!
这是100%正确的方法。 如果一个类利用了IDisposable
它应该被封装在一个using
语句中,以确保调用Dispose()
方法。 此外,不应该轻易地与在那种类似SQL Server上pipe理的外部技术进行通信。 SqlCommand
对象实现IDisposable
有一个很好的理由。 下面的代码是SqlCommand
对象的Dispose()
方法:
protected override void Dispose(bool disposing) { if (disposing) { this._cachedMetaData = null; } base.Dispose(disposing); }
正如你所看到的,它释放了对_cachedMetaData
对象的引用,所以它也可以被清理。
你可以使用下面的排版方式让代码更靠近左边:
using (SqlConnection cn = new SqlConnection("myConnectionstring")) using (SqlCommand cm = new SqlCommand("myQuery", cn)) using (SqlDataReader reader = cm.ExecuteReader()) { // read values from reader object return myReadValues; }
正如其他人已经指出的那样,使用三个嵌套的using
块是正确的。
这是正确的方法,如果你将与读者完成。 有时,你需要读者保持开放(也许你的方法返回它),所以它立即丢弃读者是行不通的。 在这些情况下,ExecuteReader的重载可以帮助您:
var cn = new SqlConnection("myConnectionstring"); var cm = new SqlCommand("myQuery", cn); var reader = cm.ExecuteReader(CommandBehavior.CloseConnection); return reader;
这将保持连接和读者打开。 一旦读取器被closures/处置,它也将closures(并处置)连接。
using(var reader = GetReader()) //which includes the code above { ... } // reader is disposed, and so is the connection.
是的,这是正确的。 你可以错过嵌套使用的大括号,因为它们是一个声明,但我不认为这增加了可读性。
这并不过分。 using
块是一个很好的做法,因为它确保即使抛出exception,也会调用对象的Dispose()
方法。
尽pipe如此,还是有这个名字的。 这就是所谓的代码糖 。 所以:
using (foo bar = new foo()) { //...snip }
简短的代码是:
foo bar = null; Exception error = null; try { bar = new foo(); // ...snip } catch (Exception ex) { error = ex; } finally { if (bar != null) bar.Dispose(); if (error != null) throw error; }
任何一种forms都与另一种forms相同,它们只是写不同的方式来写同一件事情。 换句话说, for
和while
之间for
区别是相同的:它们基本上是相同的,但是以不同的方式使用。
using
是首选,因为它使代码更短,更可读,并自动为您处置。 至于你是否应该使用它,不要听那些说你总是应该做点什么的人。 这是一个很好的习惯,但是知道什么时候使用 , 为什么要使用 , 以及使用或不使用某些东西的好处和后果比做某事更值得, 因为人们说你应该这样做 。
编辑: Eren的答案有一个例子,你不希望reader
有一个using
块。
我没有看到处置SqlCommand
任何意义。 SqlConnection
和SqlDataReader
应该被丢弃。
SqlConnection
因为当它超出范围时它不会自行closures。
SqlDataReader
可以保持SqlConnection
繁忙,直到阅读器closures。
甚至没有MSDN的例子处置的SqlCommand
。
我不是专家,但我知道使用被翻译成try / finally块,也许你可以包装SqlConnection,SqlCommand和SqlDataReader到一个独特的尝试/最后
try { // code here with SqlConnection, SqlCommand and SqlDataReader } finally { // Dispose call on SqlConnection, SqlCommand and SqlDataReader }