缺少的东西,我有以下代码:
public void Execute(string Query, params SqlParameter[] Parameters)
{
using (var Connection = new SqlConnection(Configuration.ConnectionString))
{
Connection.Open();
using (var Command = new SqlCommand(Query, Connection))
{
if (Parameters.Length > 0)
{
Command.Parameters.Clear();
Command.Parameters.AddRange(Parameters);
}
Command.ExecuteNonQuery();
}
}
}
对于不同的查询,该方法可能被调用2或3次,但方式相同。
例如
如果Point [3]失败,则不应执行所有已提交的命令,而必须回滚。
我知道我可以将SqlTransaction
放在上面并使用Commit()
方法。但是如果失败,第三点呢?我认为只有第3点会回滚,而其他1,2点不会?如何解决这个问题,我应该怎么做?
我应该使用SqlCommand []数组??我应该做什么。
using (var connection = new SqlConnection(Configuration.ConnectionString))
{
SqlCommand command = connection.CreateCommand();
SqlTransaction transaction;
connection.Open();
transaction = connection.BeginTransaction("Transaction");
command.Connection = connection;
command.Transaction = transaction;
try
{
if (Parameters.Length > 0)
{
command.Parameters.Clear();
command.Parameters.AddRange(Parameters);
}
command.ExecuteNonQuery();
transaction.Commit();
}
catch (Exception e)
{
try
{
transaction.Rollback();
}
catch (Exception ex2)
{
//trace
}
}
}
该方法可能涉及更改最少的代码,并涉及最少的复杂性是将多个SQL语句链接到单个查询中。为运行多个语句(包括Query
,BEGIN TRANSACTION
和(如果需要)COMMIT
)的ROLLBACK
参数构建字符串是完全可以的。基本上,在您的C#代码中构建整个存储过程。这也具有使程序更易于使用版本控制的好处。
但是它仍然感觉有点破旧。
减少这种影响的一种方法是标记我的Execute()
方法
private。然后,我将在类中为运行的每个查询提供一个附加方法。这样,长的SQL字符串就被隔离了,使用数据库时感觉更像是使用本地API。对于更复杂的应用程序,它可能是一个完整的单独程序集,其中的核心方法是internal
。
Execute()
方法的类型以支持交易。这里的技巧是将这种类型设置为static
是很常见的,但是支持事务需要重新使用连接对象,这意味着实例和实现IDisposable
都是如此。