强类型Dataset使用事务(改进原有方法)

原创 2015年11月21日 16:11:44

以下部份转自:http://blog.csdn.net/nfbing/article/details/5803980


关于强类型Dataset的用法和好处,我就不再多说,网上关于这方面的资料很多 , 感兴趣的话可以在GoOGLE搜一下。

我们直奔主题,好处是很多,但若使用事务的话就不方便了。最近通过查找国外的资料,总于找到解决的方法。经过自己测试发现很好用,所以把代码贴出来,给正处于这方面困惑的朋友解答:

 

首先写一个类文件,代码如下:

 

    public class HelperTA
    {

        public static SqlTransaction BeginTransaction(object tableAdapter)
        {
            return BeginTransaction(tableAdapter, IsolationLevel.ReadUncommitted);
        }

        public static SqlTransaction BeginTransaction(object tableAdapter, IsolationLevel isolationLevel)
        {
            // get the table adapter's type
            Type type = tableAdapter.GetType();

            // get the connection on the adapter
            SqlConnection connection = GetConnection(tableAdapter);

            // make sure connection is open to start the transaction
            if (connection.State == ConnectionState.Closed)
                connection.Open();

            // start a transaction on the connection
            SqlTransaction transaction = connection.BeginTransaction(isolationLevel);

            // set the transaction on the table adapter
            SetTransaction(tableAdapter, transaction);

            return transaction;
        }

        /// <summary>
        /// Gets the connection from the specified table adapter.
        /// </summary>
        private static SqlConnection GetConnection(object tableAdapter)
        {
            Type type = tableAdapter.GetType();
            PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
            SqlConnection connection = (SqlConnection)connectionProperty.GetValue(tableAdapter, null);
            return connection;
        }

        /// <summary>
        /// Sets the connection on the specified table adapter.
        /// </summary>
        private static void SetConnection(object tableAdapter, SqlConnection connection)
        {
            Type type = tableAdapter.GetType();
            PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
            connectionProperty.SetValue(tableAdapter, connection, null);
        }

        /// <summary>
        /// Enlists the table adapter in a transaction.
        /// </summary>
        public static void SetTransaction(object tableAdapter, SqlTransaction transaction)
        {
            // get the table adapter's type
            Type type = tableAdapter.GetType();

            // set the transaction on each command in the adapter
            PropertyInfo commandsProperty = type.GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.Instance);
            SqlCommand[] commands = (SqlCommand[])commandsProperty.GetValue(tableAdapter, null);
            foreach (SqlCommand command in commands)
                command.Transaction = transaction;

            // set the connection on the table adapter
            SetConnection(tableAdapter, transaction.Connection);
        }
    }
 

 

然后在你使用TableAdapter 的类文件中使用上面的类:

 

        public int InsertTest(Book book)
        {
            SqlTransaction transaction = null;

            try
            {
                int? myresult = 0;
                using (SKUTableAdapter barAdapter = new SKUTableAdapter())
                {
                    transaction = HelperTA .BeginTransaction(barAdapter);
                    barAdapter.SP_InsertSku("dfsdf", "contentname", 2, "", ref myresult);
                }

                using (UserEvaluateTableAdapter EvaluateAdapter = new UserEvaluateTableAdapter())
                {
                    HelperTA .SetTransaction(EvaluateAdapter, transaction);
                    EvaluateAdapter.InsertQuery(Guid.NewGuid().ToString(), "username", "szevaluate", 2);
                }

                int? result = 0;
                using (tb_BookTableAdapter bookadapter = new tb_BookTableAdapter())
                {
                    HelperTA .SetTransaction(bookadapter, transaction);
                    bookadapter.SP_CheckDuplicateEbook("title", "code", 2, System.DateTime.Now, ref result);
                }

                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
            finally
            {
                transaction.Dispose();
            }

            return 1;
        }


以上内容转自nfbing的专栏:http://blog.csdn.net/nfbing/article/details/5803980


使用后发现不能针对TableAdapter自动生成的Insert/Update/Delete进行事务处理,可以对添加的查询(SQL或者存储过程)进行事务处理。所以如果想使用xxTableAdapter.Update(xxTable)一类的更新就有问题了。方法是自己写代码为TableAdapter加带事务的方法,但没有这个通用性好,需要每个去编写。


经过实验,将原来的代码部份更改,并更新相应的TableAdapter类即可实现较好的效果:


更新后类代码:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;

/// <summary>
/// 为强类型的DataSet中的TableAdapter提供事务支持
/// </summary>
public class HelperTA
{
    /// <summary>
    /// 开始事务,第一个tableAdapter中使用,接受脏读
    /// </summary>
    /// <param name="tableAdapter"></param>
    /// <returns>返回一个SqlTransaction</returns>
    public static SqlTransaction BeginTransaction(object tableAdapter)
    {
        return BeginTransaction(tableAdapter, IsolationLevel.ReadUncommitted);
    }

    /// <summary>
    /// 开始事务,第一个tableAdapter中使用,可设置接受脏读及其它参数
    /// </summary>
    /// <param name="tableAdapter"></param>
    /// <param name="isolationLevel">事务锁定行为</param>
    /// <returns>返回一个SqlTransaction</returns>
    public static SqlTransaction BeginTransaction(object tableAdapter, IsolationLevel isolationLevel)
    {
        // get the table adapter's type
        Type type = tableAdapter.GetType();

        // get the connection on the adapter
        SqlConnection connection = GetConnection(tableAdapter);

        // make sure connection is open to start the transaction
        if (connection.State == ConnectionState.Closed)
            connection.Open();

        // start a transaction on the connection
        SqlTransaction transaction = connection.BeginTransaction(isolationLevel);

        // set the transaction on the table adapter
        SetTransaction(tableAdapter, transaction);

        return transaction;
    }

    /// <summary>
    /// Gets the connection from the specified table adapter.
    /// </summary>
    private static SqlConnection GetConnection(object tableAdapter)
    {
        Type type = tableAdapter.GetType();
        PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
        SqlConnection connection = (SqlConnection)connectionProperty.GetValue(tableAdapter, null);
        return connection;
    }

    /// <summary>
    /// 设置 table adapter 的连接属性(自动调用)
    /// </summary>
    private static void SetConnection(object tableAdapter, SqlConnection connection)
    {
        Type type = tableAdapter.GetType();
        PropertyInfo connectionProperty = type.GetProperty("Connection", BindingFlags.NonPublic | BindingFlags.Instance);
        connectionProperty.SetValue(tableAdapter, connection, null);
    }

    /// <summary>
    /// 将新的tableAdapter加入到事务中
    /// </summary>
    /// <param name="tableAdapter"></param>
    /// <param name="transaction"></param>
    public static void SetTransaction(object tableAdapter, SqlTransaction transaction)
    {
        // get the table adapter's type
        Type type = tableAdapter.GetType();

        // set the transaction on each command in the adapter
        PropertyInfo commandsProperty = type.GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.Instance);
        SqlCommand[] commands = (SqlCommand[])commandsProperty.GetValue(tableAdapter, null);
        foreach (SqlCommand command in commands)
            command.Transaction = transaction;

        //设置自动生成的增、删、改命令事务
        PropertyInfo AdapterProperty = type.GetProperty("Adapter", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Static);
        SqlDataAdapter adapter = (SqlDataAdapter)AdapterProperty.GetValue(tableAdapter, null);
        if (adapter.InsertCommand != null) adapter.InsertCommand.Transaction = transaction;
        if (adapter.UpdateCommand != null) adapter.UpdateCommand.Transaction = transaction;
        if (adapter.DeleteCommand != null) adapter.DeleteCommand.Transaction = transaction;


        // set the connection on the table adapter
        SetConnection(tableAdapter, transaction.Connection);
    }
}


相关文章推荐

SQL SERVER数据类型与C#数据类型对照表

http://blog.csdn.net/chgfno1/article/details/3465282 简称 .NET 类 类型 宽度 范围(位) ...

在线更新SQL Server千万级记录的大表

某表含有2000万+记录行,80+字段,10+索引,单表含索引数据达27GB 由于业务变动,导致此表中的3个字段值需进行变更,即 --更新3个字段 UPDATE big_table SET PA...

使用强类型DataSet增加数据并获取自动增长的ID

使用强类型的DataSet可以方便的操作数据库;有时候我们会对表的ID设置为自动增长,并且需要在插入数据后获取新插入数据的ID,按以下方法即可达到目的: 一、     首先建立一个表,id为自动增加...

Oracle 中使用 ObjectDataSource 读取强类型 DataSet 数据集

这一篇博文呢,将主要是介绍如何使用 ObjectDataSource 来读取数据集文件 .xsd 中的数据, 和以往唯一不同的就是,这些数据表来自 Oralce 数据库,而非 Sql Serve...

用好vs2005之使用强类型DataSet简化开发

http://hi.baidu.com/chenying99/blog/item/21e497a1a9a73c8f461064fb.html 在日常开发中,为了编写数据的增加、更新、修改、删...
  • plean
  • plean
  • 2011年07月07日 16:49
  • 217

winform 强类型DataSet源码

  • 2009年11月26日 14:16
  • 82KB
  • 下载

使用非类型化的DataSet完成用户信息的增删改查操作

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> http://www.w3.org/1999/xhtml">

.NET“类型化数据集(Typed Dataset)”使用心得 - 2. 创建

2.1.  建立Typed DataSet 右键单击要建立Typed DataSet的项目,选择Add-> New Item。然后选择C#下,Data类别,选择DataSet,起一个[名字],然后点...
  • mfn2005
  • mfn2005
  • 2012年05月09日 16:10
  • 325

Typed DataSet强类型Oracle的delete,update,insert

1.DELETE FROM "SALGRADE" WHERE id = :id 2.INSERT INTO "SALGRADE" ("GRADE",  "ID", "TEST") VALUES (:...
  • luolunz
  • luolunz
  • 2012年08月11日 13:57
  • 1256

强类型DataSet的基本知识

“typed DataSet是从DataSet派生的,它根据事先定义的Data Schema生成数据集,对数据集中的字段实行强类型约束。你可以通过它产生的cs文件看到许多方法对DataTable的操作...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:强类型Dataset使用事务(改进原有方法)
举报原因:
原因补充:

(最多只允许输入30个字)