处理SqlCommand
Disposing SqlCommand
因为 SqlCommand
实现了 IDisposable
,我通常会按如下方式处理 ADO 查询。
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
{
// Execute command, etc. here
}
但是,如果我需要在单个连接期间执行多个命令怎么办?我真的需要为每个命令创建一个新的 using
块吗?
我从 Microsoft 找到的示例不使用 using
块 SqlCommand
(甚至调用 Dispose()
)。关于处置 SqlCommand
的最佳做法是什么?
using 语句确保即使在调用对象的方法时发生异常,也会调用 Dispose
。您可以通过将对象放在 try 块中然后在 finally
块中调用 Dispose
来获得相同的结果。
在这种情况下,您对每个命令块使用 using
:
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd1= new SqlCommand(query1, connection))
{
}
using (SqlCommand cmd2= new SqlCommand(query2, connection))
{
}
}
当然,最好的做法是处理它们。
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command1 = new SqlCommand(query1, connection))
{
// Execute command, etc. here
}
using (SqlCommand command2 = new SqlCommand(query2, connection))
{
// Execute command, etc. here
}
using (SqlCommand command3 = new SqlCommand(query3, connection))
{
// Execute command, etc. here
}
}
MSDN 可能不会显示它,因为在 SqlCommand
的情况下它是 not really needed。但在我看来,微软不在每个实现 IDdisosable
的对象上使用这种模式是不好的,因为人们不习惯它。
最佳做法是,如果它实现了 IDisposable,那么就对它进行 Dispose()。 事实上,示例 here 都调用了 Dispose。有皱纹:
第一个示例打开 SqlDataReader,在 finally 子句中对命令调用 .Close()。事实上,.Close 只是 .Dispose() 的包装器(并且不再出现在文档中)。 Jonathan Wood 在他的评论中指出 Close 在 reader.这是错误的。
对于同一连接上的多个呼叫,您可以:
- Re-use 一个命令(在一个使用中声明)。我不喜欢这个
我自己,但那只是我:我发现它......丑陋。
- 在多次使用中使用多个命令。这就是我要做的。
'Best Practice' 有点乱。从来没有一致认为 A 吹捧为最佳实践的人比 B 推荐的人更好,更不用说 C、D 或 E 了。请自行判断。
不,你没有。有两种方法可以将您的多个命令捆绑在一个连接和命令中。
第一种是仅重用现有的 CMD 对象,但根据需要更改 CommandText 和其他 CMD.properties。
using (SqlConnection con = new SqlConnection(connectionString)) {
con.Open();
using (SqlCommand cmd = new SqlCommand(query1, con)) {
// cmd.CommandType = CommandType.xxxxx
// add any parameters
// Execute()
cmd.CommandText = query2;
// reset CommandType if needed
// adjust parameters if needed
// Execute()
cmd.CommandText = query 3;
// reset CommandType if needed
// adjust parameters if needed
// Execute()
}
con.Close();
}
第二种方法是在数据库服务器上创建一个存储过程并在一个CMD对象中调用它
-- Database
CREATE PROCEDURE schema.sproc_CommandBatch (
-- any variables here
) AS
BEGIN
-- query 1
-- query 2
-- query 3
END
GO
// C#
using (SqlConnection con = new SqlConnection(connectionString)) {
con.Open();
using (SqlCommand cmd = new SqlCommand("schema.sproc_CommandBatch", con)) {
// cmd.CommandType = CommandType.StoredProcedure
// add any parameters
// Execute()
}
con.Close();
}
因为 SqlCommand
实现了 IDisposable
,我通常会按如下方式处理 ADO 查询。
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
{
// Execute command, etc. here
}
但是,如果我需要在单个连接期间执行多个命令怎么办?我真的需要为每个命令创建一个新的 using
块吗?
我从 Microsoft 找到的示例不使用 using
块 SqlCommand
(甚至调用 Dispose()
)。关于处置 SqlCommand
的最佳做法是什么?
using 语句确保即使在调用对象的方法时发生异常,也会调用 Dispose
。您可以通过将对象放在 try 块中然后在 finally
块中调用 Dispose
来获得相同的结果。
在这种情况下,您对每个命令块使用 using
:
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd1= new SqlCommand(query1, connection))
{
}
using (SqlCommand cmd2= new SqlCommand(query2, connection))
{
}
}
当然,最好的做法是处理它们。
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command1 = new SqlCommand(query1, connection))
{
// Execute command, etc. here
}
using (SqlCommand command2 = new SqlCommand(query2, connection))
{
// Execute command, etc. here
}
using (SqlCommand command3 = new SqlCommand(query3, connection))
{
// Execute command, etc. here
}
}
MSDN 可能不会显示它,因为在 SqlCommand
的情况下它是 not really needed。但在我看来,微软不在每个实现 IDdisosable
的对象上使用这种模式是不好的,因为人们不习惯它。
最佳做法是,如果它实现了 IDisposable,那么就对它进行 Dispose()。 事实上,示例 here 都调用了 Dispose。有皱纹:
第一个示例打开 SqlDataReader,在 finally 子句中对命令调用 .Close()。事实上,.Close 只是 .Dispose() 的包装器(并且不再出现在文档中)。 Jonathan Wood 在他的评论中指出 Close 在 reader.这是错误的。
对于同一连接上的多个呼叫,您可以:
- Re-use 一个命令(在一个使用中声明)。我不喜欢这个 我自己,但那只是我:我发现它......丑陋。
- 在多次使用中使用多个命令。这就是我要做的。
'Best Practice' 有点乱。从来没有一致认为 A 吹捧为最佳实践的人比 B 推荐的人更好,更不用说 C、D 或 E 了。请自行判断。
不,你没有。有两种方法可以将您的多个命令捆绑在一个连接和命令中。
第一种是仅重用现有的 CMD 对象,但根据需要更改 CommandText 和其他 CMD.properties。
using (SqlConnection con = new SqlConnection(connectionString)) {
con.Open();
using (SqlCommand cmd = new SqlCommand(query1, con)) {
// cmd.CommandType = CommandType.xxxxx
// add any parameters
// Execute()
cmd.CommandText = query2;
// reset CommandType if needed
// adjust parameters if needed
// Execute()
cmd.CommandText = query 3;
// reset CommandType if needed
// adjust parameters if needed
// Execute()
}
con.Close();
}
第二种方法是在数据库服务器上创建一个存储过程并在一个CMD对象中调用它
-- Database
CREATE PROCEDURE schema.sproc_CommandBatch (
-- any variables here
) AS
BEGIN
-- query 1
-- query 2
-- query 3
END
GO
// C#
using (SqlConnection con = new SqlConnection(connectionString)) {
con.Open();
using (SqlCommand cmd = new SqlCommand("schema.sproc_CommandBatch", con)) {
// cmd.CommandType = CommandType.StoredProcedure
// add any parameters
// Execute()
}
con.Close();
}