在C#中打开和关闭SQLConnections

时间:2018-10-15 14:43:28

标签: c# database sqlconnection

有人可以告诉我如何在C#中正确使用SQL连接吗?

现在我正在那样做:

//some Code here
using (var sqlConnection = DatabaseUtil.DatabaseUtil.CreateSqlConnection(connectionString)) 
{
    var cmd = new SqlCommand();

    DatabaseUtil.DatabaseUtil.InitializeSqlCommand(ref cmd, query, sqlConnection);

    sqlConnection.Open();

    using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
    {
        reader.Read();

        if (reader.HasRows)
        {
            //some code here
        }

        reader.Close();
        reader.Dispose();
    }

    sqlConnection.Close();
}

DatabaseUtil VB.NET 编写。这里的函数CreateSqlConnection

Public Function CreateSqlConnection(connectionString As String) As SqlConnection
    Dim result As SqlConnection
    result = New SqlConnection(connectionString)
    Return result
End Function

在这里您可以看到函数InitializeSqlCommand

Public Sub InitializeSqlCommand(ByRef cmd As SqlCommand, query As String, sqlConnection As SqlConnection)
    cmd.CommandText = query
    cmd.CommandType = CommandType.Text
    cmd.Connection = sqlConnection
End Sub

我做到了吗正确?还是您对我有一些改善的建议?

每一个技巧我都会很感激。

阿里

3 个答案:

答案 0 :(得分:3)

我怀疑您是否要在这里DatabaseUtil;使用new进行显式创建可以做到:

  // If you don't want to hardcode connection's type - SqlConnection -
  // (possible purpose of DatabaseUtil class) use dependency injection
  using (var sqlConnection = new SqlConnection(connectionString)) {
    sqlConnection.Open();

    // sqlConnection.CreateCommand() - we can avoid dependency 
    // and don't hardcode SqlCommand as "new SqlCommand"
    //DONE: wrap IDisposable into using, do not close it explicitly
    using (var cmd = sqlConnection.CreateCommand()) {
      cmd.CommandText = query;

      //TODO: you may want to provide Parameters here

      //DONE: wrap IDisposable into using, do not close it explicitly
      using (var reader = cmd.ExecuteReader()) {
        // reader.Read() returns true if record is read 
        // (i.e. we have at least one record)
        if (reader.Read()) {
          // We have at least one row
          // some code here
        } 
      }  
    } 
  }

如果您要读取多条记录,而不仅仅是查询返回至少一条记录的事实,请将if (reader.Read())变成while

      ... 
      //DONE: wrap IDisposable into using, do not close it explicitly
      using (var reader = cmd.ExecuteReader()) {
        // reader.Read() returns true if record is read 
        while (reader.Read()) {
          // record has been read
          // some code here 
        } 
      }  
      ...

答案 1 :(得分:2)

我首先要说的是,原始帖子本身没有什么错误,您可以继续使用该代码。

但是...我们仍然可以做得更好。

SqlCommand的{​​{1}}参数不需要通过引用传递。 IMO这是VB代码中的错误。 InitializeSqlCommand()在这里已经足够好了,ByVal将您的命令对象暴露给您可能不想要的东西。

ByRef函数中,我倾向于假设如果您正在创建连接,那么您也想尽快打开它。另外,我们可以将方法缩短一些。

我也倾向于将连接字符串直接放入等效的DatabaseUtil模块中,或者构建模块,以便它可以从配置文件中加载字符串。我不需要每次都将数据传递到CreateSqlConnection()方法中。像这样将这两段放在一起:

CreateSqlConnection()

这是一件小事,但是Private ReadOnly Property ConnectionString As String Get Return "connection string here" End Get End Property Public Function CreateSqlConnection() As SqlConnection Dim result As New SqlConnection(ConnectionString) result.Open() Return result End Function 也实现了SqlCommand,因此理想情况下它也将位于IDisposble块中。确实,现有的using方法没有什么可以用InitializeSqlCommand()构造函数直接完成的,因为SqlCommand已经是默认设置。继续并导入CommandType.Text名称空间,您可以像这样将这两段放在一起:

DatabaseUtil

我还担心一个using (var sqlConnection = DatabaseUtil.CreateSqlConnection()) using (var cmd = new SqlCommand(query, sqlConnection)) { 命令函数接受一个InitializeSqlCommand()字符串,但不提供查询参数。是的,您仍然可以稍后在代码中添加参数,但是根据我的经验,这倾向于鼓励对参数数据使用字符串连接...或更准确地说,是无法充分阻止它,这等同于同一件事。您要确保在应用程序中没有SQL Injection漏洞。如果您继续使用query,我的结构将更像这样:

InitializeSqlCommand()

如果连接是在Public Function InitializeSqlCommand(cn As SqlConnection, query As String, ParamArray paramters() As SqlParamter) As SqlCommand Dim result As SqlCommand = cn.CreateCommand() result.CommandText = query If parameters IsNot Nothing AndAlso parameter.Length > 0 Then result.Parameters.AddRange(parameters) End If Return result End Sub 块中创建的,则不必调用sqlConnection.Close()。这同样适用于DataReader。

最后,不是用于DataReader的典型模式来检查using属性。通常只需在HasRows循环中检查Read()方法的结果即可。

将所有内容放在一起,包括修订的VB功能,如下所示:

while

答案 2 :(得分:1)

您不需要DatabaseUtil。就是这样:

using (var sqlConnection =new SqlConnection(connectionString)){
   var cmd = new SqlCommand(query, sqlConnection);
   sqlConnection.Open();
   var reader = cmd.ExecuteReader();
   while(reader.Read())
    {
         //do whatever you want
    };
}

使用using时不需要关闭连接。

相关问题