在 C# 中打开和关闭 SQLConnections
Opening and closing SQLConnections in C#
有人能告诉我如何在 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
我这样做对吗?或者你对我有什么改进的建议吗?
我将不胜感激。
阿里
我怀疑你是否想要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
}
}
}
}
如果你想读取多条记录而不仅仅是查询returns至少一条记录的事实,将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
}
}
...
您不需要 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
时无需关闭连接。
我首先要说的是 post 本身 是错误的 ,您可以继续使用该代码。
但是...我们还可以做得更好。
InitializeSqlCommand()
的 SqlCommand
参数不需要通过 ref。 IMO 这是 VB 代码中的一个错误。 ByVal
在这里已经足够好了,ByRef
将您的命令对象暴露给您可能不想要的东西。
在 CreateSqlConnection()
函数中,我倾向于假设如果您正在创建一个连接,您也会希望很快打开它。另外,我们可以缩短一些方法。
我也倾向于将我的连接字符串直接放入等效的 DatabaseUtil 模块,或者构建模块以便它可以从配置文件加载字符串。我不想每次都将该数据传递给 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))
{
我还担心接受 query
字符串但未提供查询参数的 InitializeSqlCommand()
命令函数。是的,您仍然可以稍后在代码中添加参数,但根据我的经验,这往往会鼓励对参数数据使用字符串连接……或者更准确地说,未能充分阻止它,这相当于同一件事。您要确保应用程序中没有 SQL 注入漏洞。如果你继续使用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
如果连接是在 using
块中创建的,则无需调用 sqlConnection.Close()
。这同样适用于 DataReader。
最后,DataReader 的典型模式是而不是 检查HasRows
属性。通常 仅 检查 Read()
方法的结果就足够了,并且通常在 while
循环中。
把它们放在一起,包括修改后的 VB 函数,像这样:
var parameters = new SqlParameter[] { }; //define parameters here
using (var sqlConnection = DatabaseUtil.CreateSqlConnection())
using (var cmd = DatabaseUtil.InitializeSqlCommand(sqlConnection, query, parameters))
using (var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
//some code here
}
}
有人能告诉我如何在 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
我这样做对吗?或者你对我有什么改进的建议吗?
我将不胜感激。
阿里
我怀疑你是否想要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
}
}
}
}
如果你想读取多条记录而不仅仅是查询returns至少一条记录的事实,将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
}
}
...
您不需要 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
时无需关闭连接。
我首先要说的是 post 本身 是错误的 ,您可以继续使用该代码。
但是...我们还可以做得更好。
InitializeSqlCommand()
的 SqlCommand
参数不需要通过 ref。 IMO 这是 VB 代码中的一个错误。 ByVal
在这里已经足够好了,ByRef
将您的命令对象暴露给您可能不想要的东西。
在 CreateSqlConnection()
函数中,我倾向于假设如果您正在创建一个连接,您也会希望很快打开它。另外,我们可以缩短一些方法。
我也倾向于将我的连接字符串直接放入等效的 DatabaseUtil 模块,或者构建模块以便它可以从配置文件加载字符串。我不想每次都将该数据传递给 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))
{
我还担心接受 query
字符串但未提供查询参数的 InitializeSqlCommand()
命令函数。是的,您仍然可以稍后在代码中添加参数,但根据我的经验,这往往会鼓励对参数数据使用字符串连接……或者更准确地说,未能充分阻止它,这相当于同一件事。您要确保应用程序中没有 SQL 注入漏洞。如果你继续使用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
如果连接是在 using
块中创建的,则无需调用 sqlConnection.Close()
。这同样适用于 DataReader。
最后,DataReader 的典型模式是而不是 检查HasRows
属性。通常 仅 检查 Read()
方法的结果就足够了,并且通常在 while
循环中。
把它们放在一起,包括修改后的 VB 函数,像这样:
var parameters = new SqlParameter[] { }; //define parameters here
using (var sqlConnection = DatabaseUtil.CreateSqlConnection())
using (var cmd = DatabaseUtil.InitializeSqlCommand(sqlConnection, query, parameters))
using (var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
//some code here
}
}