我有一个像这样的sqlConnection管理器类:
public class SQLConn {
public string connStr = System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
private SqlConnection sqlConn;
public SqlConnection Connection()
{
sqlConn = new SqlConnection(connStr);
return sqlConn;
}
public void Open()
{
sqlConn .Open();
}
}
如果我使用带有'using'语句的函数,如:
var conn = new SQLConn();
using (conn.Connection())
{
String query = "Select * from table";
objSql = new SqlCommand(query, conn.Connection());
conn.Open();
DoSomething();
}
由于conn.Connection()
返回SqlConnection对象,using语句是否会自动处理连接?或者,我是否必须在SqlConn类上实现IDisposable和自定义Dispose方法?
这甚至是一个好方法吗?我正在使用遗留代码,但我还无法使用ORM,但有没有办法简化现有模式来管理/创建SQL连接?
答案 0 :(得分:12)
using
语句将查看表达式的最终类型 - 即从.Connection()
返回的任何内容;如果这返回的内容为IDisposable
,那么你就可以了。
编译器会告诉您是否出错;-p(不允许您对不是using
的内容使用IDisposable
。
您应该注意创建两个连接的位置:
using (var c = conn.Connection()) // <==edit
{
String query = "Select * from table";
objSql = new SqlCommand(query, c); // <==edit
c.Open();
DoSomething();
}
可能:
public SqlConnection Connection()
{
if(sqlConn == null) sqlConn = new SqlConnection(connStr); // <== edit
return sqlConn;
}
答案 1 :(得分:5)
它会起作用但在using {}
之后你会留下一个内部持有Disposed SqlConnection的sqlConn。不是一个非常有用的情况
答案 2 :(得分:1)
你的代码错了!应该是这样的:
Dim conn as New SQLConn();
Dim sqlConnection New SQLConnection();
sqlConnection = conn.Connection();
using (sqlConnection)
{
String query = "Select * from table";
objSql = new SqlCommand(query, sqlConnection);
conn.Open();
DoSomething();
}
这样,using语句将在最后处理连接。
答案 3 :(得分:1)
要回答您的标题问题,您必须在您使用“使用”对象的类中实现IDisposable。否则,您将收到编译时错误。
然后,是的,“using”会在块的末尾处理你的SqlConnection。将“使用”想象为“try-finally”:在“finally”块中隐式调用Dispose()。
最后,更清洁的代码将是:
using( SqlConnection = new SqlConnection( connStr ) {
// do something
}
至少读者的代码不必花费精力去实现,因为Henk Holterman指出你的SQLConn对象持有对已处置连接的引用。
答案 4 :(得分:1)
澄清上述内容:
您需要使用的任何对象都应该放在using语句的末尾。因此,编译器需要确保您的类型在看到使用该类型对象时实现IDisposable接口,或者它不会让您离开。
答案 5 :(得分:0)
不,不,只要返回的对象是IDisposable。
返回的对象不需要实现IDisposable,但是使用block将没有用处。
答案 6 :(得分:0)
答案 7 :(得分:0)
似乎连接将正确关闭,但不建议这样做:
您可以实例化资源 对象然后将变量传递给 使用声明,但这不是一个 最佳实践。在这种情况下, 对象在控制后仍然在范围内 即使它离开使用块 将来可能无法访问 它的非托管资源。其他 话说,它将不再完整 初始化。如果你试图使用 在使用块之外的对象,你 造成例外的风险 抛出。因此,它是 通常更好地实例化 using语句中的对象和 将其范围限制为使用块。