做一个ADO.. NET事务需要在使用Connection.CreateCommand()时分配给命令对象

本文关键字:CreateCommand Connection 对象 命令 分配 一个 ADO NET 事务 | 更新日期: 2023-09-27 17:49:43

我需要使用ADO事务。净提供者。

下面是创建连接、事务和命令的简单示例。当我使用connection.CreateCommand()创建命令时,我是否需要将事务分配给该命令?或者,事务集是因为我使用connection.CreateCommand()而不是新建一个命令对象吗?

var connection = Database.GetConnection();
connection.Open();
var transaction = connection.BeginTransaction();
var command = connection.CreateCommand();
command.Transaction = transaction; // Is this line needed when using connection.CreateCommand()?

* 更新*

当我测试两个对象的引用时,它们是相同的。我认为这意味着connection.CreateCommand()是返回一个命令与分配的事务。或者这不是一个有效的测试。

using (var connection = Database.GetConnection())
{
    connection.Open();
    var transaction = connection.BeginTransaction();
    var command = connection.CreateCommand();
    if (object.ReferenceEquals(transaction, command.Transaction))
        Debug.WriteLine("EQUAL");
}

做一个ADO.. NET事务需要在使用Connection.CreateCommand()时分配给命令对象

您必须为每个SqlCommand实例显式设置事务。以下是CreateCommandSystem.Data.SqlClient.SqlConnection.cs的源代码(第782行):

new public SqlCommand CreateCommand() {
    return new SqlCommand(null, this);
}

如你所见;它将null传递给CommandText,将this(自身)传递给SqlConnection参数。

是的,事务和命令需要相互关联。

一些编辑过的示例代码:

// Connect to the database.
SqlConnection connection = new SqlConnection(Database.ConnectionString);
connection.Open();
// Start a transaction.
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.Transaction = connection.BeginTransaction(System.Data.IsolationLevel.Serializable, "ryan");
// Delete any previously associated targets.
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "FirstSP";
command.Parameters.AddWithValue("@Id", this.Id);
command.ExecuteNonQuery();
// Add the specified targets to the product.
command.CommandText = "SecondSP";
command.Parameters.Add("@Id", SqlDbType.Int);
foreach (int Id in Ids)
{
    command.Parameters["@Id"].Value = Id;
    command.ExecuteNonQuery();
}
// Commit the transaction.
command.Transaction.Commit();
// Houseclean.
connection.Close();

如果您使用TransactionScope,则不需要向命令对象附加任何内容。

请看TransactionScope文档中的示例

using (var connection = new SqlConnection(Database.ConnectionString))
{
   connection.Open();
   using (var trans = connection.BeginTransaction())
   {
       using (var command = trans.Connection.CreateCommand())
       { 
          command.CommandText = 'DELETE FROM TABLE_NAME WHERE ID = ?'; 
          command.Transaction = trans;
          command.ExecuteNonQuery();
       }
       trans.Commit();
   }
}

如果您使用connection.CreateCommand,并且连接已经启动了一个事务,那么生成的命令对象将被征召到事务中(命令的事务属性将被设置)。

如果您使用new Command,您必须显式设置事务