如果多个语句中的任何其他语句失败,如何反转查询影响?

How do I reverse the query affect if any of the other statement fails among several statements?

var sqlCommand= "@ DELETE FROM table1 WHERE id = @Id
                   DELETE FROM table2 WHERE id = @Id ";

var isDeleted = db.Database
                  .ExecuteSqlCommand(sqlCommand, new SqlParameter("@Id", Id)) > 0;

问题是,如果第二个或任何其他语句失败,那么前面的语句将保持不变,即已被删除。

如果其中任何一个失败并且 return 错误,我希望它反转。

注意:必须按同样的方式进行,不能在存储过程中进行。

在 C# 中,您可以像这样使用 TransactionScope

using (TransactionScope t = new TransactionScope(TransactionScopeOption.Required))
{
   //do your work
   if(everything is ok)
     t.Complete();
}
    public void YourMethod(Sqlconnection conn,int id)
    {
        conn.Open();
        using (SqlTransaction oTransaction = conn.BeginTransaction())
        {
            using (SqlCommand command = conn.CreateCommand())
            {
                string query =
                       "DELETE FROM table1 WHERE id=@Id;" +
                       "DELETE FROM table2 WHERE id=@Id;";
                command.CommandText = query;

                command.Parameters.Add(new SqlParameter("@Id", SqlDbType.Int));

                command.Transaction = oTransaction;
                command.CommandType = CommandType.Text;

                try
                {
                    command.Parameters[0].Value = id;
                    command.ExecuteNonQuery();


                    //start transaction
                    oTransaction.Commit();
                }
                catch (Exception)
                {
                    //if the transaction fails then rollback the data
                    oTransaction.Rollback();
                    //notice the call method that there was an exception
                    throw;
                }
                finally
                {
                    // Close connection
                    conn.Close();
                }
            }
        }
    }

EF 让这对您来说非常简单:

var isDeleted = db.Database.ExecuteSqlCommand(
    TransactionalBehavior.EnsureTransaction, // <=== new
    sqlCommand, new SqlParameter("@Id", Id)) > 0;

最好for many reasons 使用BEGIN TRAN COMMIT 而不是使用客户端事务。确保有 XACT_ABORT ON 以防止出现异常时出现悬空事务

var sqlCommand= @"
SET XACT_ABORT ON;
BEGIN TRAN;

DELETE FROM table1 WHERE id = @Id;
DELETE FROM table2 WHERE id = @Id;

COMMIT TRAN;
";

var isDeleted = db.Database
                  .ExecuteSqlCommand(sqlCommand, new SqlParameter("@Id", Id)) > 0;