如何在C#中使用带有类型化数据集的事务?

时间:2011-03-23 01:55:12

标签: c# sql-server database

您好 如何使用带有类型化数据集的事务?假设我有一个记录表和记录详细信息表,我将在记录表中保存一个,并在记录详细信息表中保存所有详细信息。 我该怎么用?我发现事务可以用于非类型化数据集,但我没有看到它与类型化数据集。有人可以告诉我应该怎么做吗?

凯文

3 个答案:

答案 0 :(得分:5)

在CodeProject上有一个nice article(和代码),关于如何扩展类型化数据集以启用事务,而不会在使用TransactionScope时将它们提升为分布式事务。

摘要:使用事务范围和在partial类上添加的方法来修改底层SqlCommand对象以参与同一事务。

using (SqlTransaction transaction = connection.BeginTransaction())
{
       // These methods will update all relevant command objects’ transaction property
       adapter1.EnlistTransaction(transaction);
       adapter2.EnlistTransaction(transaction);

       adapter1.Update(table1);
       adapter2.Update(table2);

       transaction.Commit();
}

来自参考的适配器的代码示例:

public partial class [TableAdapterName]
{
    public void EnlistTransaction(System.Data.SqlClient.SqlTransaction transaction)
    {
        System.Data.SqlClient.SqlTransaction _transaction;

        if (this._transaction != null)
        {
            throw new System.InvalidOperationException
        ("This adapter has already been enlisted in a transaction");
        }
        else
        {
            this._transaction = transaction;
            Adapter.UpdateCommand.Transaction = _transaction;
            Adapter.InsertCommand.Transaction = _transaction;
            Adapter.DeleteCommand.Transaction = _transaction;
        }
    }
}

答案 1 :(得分:1)

您可以使用TransactionScope并调用TransactionScope对象范围内的更新。

请参阅此链接中提供的示例。 TransactionScope

提供了一个更为贴心的示例here

答案 2 :(得分:1)

我不建议使用transactionscope,因为处理代码重构很困难,因为你可以包装大量的代码,这就是我的建议:

这个答案不同,因为它为所有命令添加了事务,而不仅仅是为了持久性

扩展您的部分Adapter类:

partial class YourTableAdapter
{
    public SqlTransaction Transaction
    {
        set
        {
            if (this.CommandCollection != null)
            {
                for (int i = 0; i < this.CommandCollection.Length; i++)
                {
                    this.CommandCollection[i].Connection = value.Connection;
                    this.CommandCollection[i].Transaction = value;
                }
            }

            this.Connection = value.Connection;
            this._adapter.AplicaTransaction(value);
        }
    }
}

扩展方法:

namespace System
{
    public static class DALSqlExtension
    {
        public static void AplicaTransaction(this SqlDataAdapter _adapter, SqlTransaction transaction)
        {
            if (_adapter == null)
            {
                return;
            }
            if (_adapter.InsertCommand != null)
            {
                _adapter.InsertCommand.Transaction = transaction;
                _adapter.InsertCommand.Connection = transaction.Connection;
            }
            if (_adapter.UpdateCommand != null)
            {
                _adapter.UpdateCommand.Transaction = transaction;
                _adapter.UpdateCommand.Connection = transaction.Connection;
            }
            if (_adapter.DeleteCommand != null)
            {
                _adapter.DeleteCommand.Transaction = transaction;
                _adapter.DeleteCommand.Connection = transaction.Connection;
            }
            if (_adapter.SelectCommand != null)
            {
                _adapter.SelectCommand.Transaction = transaction;
                _adapter.SelectCommand.Connection = transaction.Connection;
            }
        }
    }
}