我发现在我的每个查询(需要自己的命令或写参数.clear())上编写一个using语句非常烦人,有时需要在using块之外声明变量。与没有丢弃物体的版本相比,它非常令人讨厌并且看起来更脏。
我需要处理它吗?如果我不这样做会发生什么?我知道在有对象时处理对象的好习惯。
答案 0 :(得分:5)
从Reflector快速浏览一下,它似乎在其PreparableStatement上调用CloseStatement(),然后在其超类上调用Dispose(),包括System.ComponentModel.Component。在链的某个地方,它最终调用NativeDriver.CloseStatement32(id),它将命令写入连接流。
这不是我想要跳过的那种东西。为何冒风险?
这是您需要调整自己思维的时候之一。你可能会认为using
看起来很“脏”,但是 - 就像新鲜的油在齿轮系统上闪闪发光 - 它实际上是清洁的标志。你或许可以写一个抽象来隐藏它,但是你不应该把它去掉。
答案 1 :(得分:2)
如果你的目标是ASP.NET,你可以设置你的Connect()方法(如果你有的话)也设置一个终结器,以便在页面卸载时运行。如果您遇到连接池问题,这个技巧也很棒。
我还包含了一个Exec方法来简化使用类型安全参数编写SQL命令的方法 - 就像在Test方法中一样。
using System;
using System.Web;
using System.Data.SqlClient;
using Conf = System.Configuration.ConfigurationManager;
using System.Data;
public static class Sql {
public static SqlConnection Connect() {
// create & open connection
SqlConnection result = new SqlConnection(Conf.ConnectionStrings["connectionString"].ConnectionString);
result.Open();
// add delegate to trigger when page has finished, to close the connection if it still exists
System.Web.UI.Page page = HttpContext.Current.Handler as System.Web.UI.Page;
if (page != null) {
page.Unload += (EventHandler)delegate(object s, EventArgs e) {
try {
result.Close();
} catch (Exception) {
} finally {
result = null;
}
};
}
// return connection
return result;
}
public static SqlDataReader Exec(string name, params object[] parameters) {
using (SqlCommand cmd = Connect().CreateCommand()) {
cmd.CommandTimeout = int.Parse(Conf.AppSettings["commandTimeoutSec"]);
cmd.CommandType = CommandType.Text;
cmd.CommandText = name;
for (int x = 0; x + 1 < parameters.Length; x += 2) {
SqlParameter p = cmd.Parameters.AddWithValue((string)parameters[x], parameters[x + 1]);
if (parameters[x + 1] is string) {
p.DbType = DbType.AnsiString;
}
}
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
}
public static void Test() {
using (SqlDataReader reader = Exec(
"SELECT * FROM member WHERE name=@firstname AND age=YEAR(GETDATE())-@yearborn",
"@firstname", "tom",
"@yearborn", 1978)) {
while (reader.Read()) {
// read
}
}
}
}