8

我有一个这样的 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();
  }
}

如果我使用带有“使用”语句的函数,例如:

var conn = new SQLConn();

using (conn.Connection()) 
{ 
    String query = "Select * from table";
    objSql = new SqlCommand(query, conn.Connection());      

    conn.Open(); 
    DoSomething(); 
}

using 语句是否会自动处理连接,因为conn.Connection()返回一个 SqlConnection 对象?或者,我是否必须在 SqlConn 类上实现 IDisposable 和自定义 Dispose 方法?

这甚至是一个好方法吗?我正在使用遗留代码,我还不能使用 ORM,但是有没有办法简化这个现有的模式来管理/创建 SQL 连接?

4

8 回答 8

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;
}
于 2009-05-27T10:33:10.603 回答
5

它会起作用,但之后using {}你会留下一个内部持有一个 Disposed SqlConnection 的 sqlConn。不是一个真正有用的情况

于 2009-05-27T10:36:46.600 回答
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 语句将在最后处理连接。

于 2009-05-27T10:37:45.460 回答
1

要回答您的标题问题,您必须在使用“using”的对象的类中实现 IDisposable。否则,您将收到编译时错误。

然后,是的,“使用”将在块的末尾处理您的 SqlConnection 。将“使用”视为“最终尝试”:在“最终”块中有对 Dispose() 的隐式调用。

最后,更简洁的代码将是:

using( SqlConnection = new SqlConnection( connStr ) {
    // do something
}

正如 Henk Holterman 指出的,您的 SQLConn 对象拥有对已处置连接的引用,至少您的代码的读者不必费力地意识到这一点。

于 2009-05-27T10:58:45.993 回答
1

为了澄清上面所说的:

您需要与 using 一起使用的任何对象都应在 using 语句的末尾进行处理。因此,编译器需要确保您的类型在看到使用该类型对象时实现 IDisposable 接口,否则它不会让您离开。

于 2012-02-27T20:16:47.757 回答
0

不,你不需要,只要返回的对象是 IDisposable。

返回的对象不需要实现 IDisposable,但是 using 块将毫无用处。

于 2009-05-27T10:32:17.297 回答
0

来自MSDN

提供给 using 语句的对象必须实现 IDisposable 接口。

但是,您不必调用 Dispose(),using 语句隐含地为您执行此操作。

于 2009-05-27T10:34:48.790 回答
0

似乎连接会正确关闭,但不建议这样做:

您可以实例化资源对象,然后将变量传递给 using 语句,但这不是最佳实践。在这种情况下,对象在控制离开 using 块后仍保留在范围内,即使它可能不再有权访问其非托管资源。换句话说,它将不再被完全初始化。如果您尝试在 using 块之外使用该对象,则可能会引发异常。出于这个原因,通常最好在 using 语句中实例化对象并将其范围限制在 using 块中。

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

于 2009-05-27T10:39:45.143 回答