以下部份转自: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);
}
}

强类型Dataset使用事务(改进原有方法)的更多相关文章

  1. 强类型DataSet的使用简明教程

    关于弱类型 DataSet的缺点: 无论何时从 DataSet检索值都是以Object类型返回,需要对它进行类型转换: 给其它开发者使用 时无法知道哪些列可用: 运行时才能知道所 有列名,数据绑定麻烦 ...

  2. Web Service 中返回DataSet结果的几种方法

    Web Service 中返回DataSet结果的几种方法: 1)直接返回DataSet对象    特点:通常组件化的处理机制,不加任何修饰及处理:    优点:代码精减.易于处理,小数据量处理较快: ...

  3. uvm_tlm——TLM1事务级建模方法(一)

    TLM(事务级建模方法,Transaction-level modeling)是一种高级的数字系统模型化方法,它将模型间的通信细节与函数单元或通信架构的细节分离开来.通信机制(如总线或者FIFO)被建 ...

  4. 【翻译自mos文章】当并行事务恢复进程在执行时,禁用并行事务恢复的方法

    当并行事务恢复进程在执行时,禁用并行事务恢复的方法 How to Disable Parallel Transaction Recovery When Parallel Txn Recovery is ...

  5. 2强类型DataSet (2011-12-30 23:16:59)转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 http://blog.sina.com.cn/s/blog_9d90c4140101214w.html

    强类型DataSet (2011-12-30 23:16:59) 转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 using System; using System.Collections.G ...

  6. 强类型DataSet (2011-12-30 23:16:59)转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 http://blog.sina.com.cn/s/blog_9d90c4140101214w.html

    强类型DataSet (2011-12-30 23:16:59) 转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 using System; using System.Collections.G ...

  7. 什么叫强类型的DATASET ?对DATASET的操作处理?强类型DataSet的使用简明教程

    强类型DataSet,是指需要预先定义对应表的各个字段的属性和取值方式的数据集.对于所有这些属性都需要从DataSet, DataTable, DataRow继承,生成相应的用户自定义类.强类型的一个 ...

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

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

  9. Web Service 中返回DataSet结果大小改进

    http://www.cnblogs.com/scottckt/archive/2012/11/10/2764496.html Web Service 中返回DataSet结果方法: 1)直接返回Da ...

随机推荐

  1. mac下安装xampp、及其之上的组件安装

    由于mac下开发需要用到php7,这里是用的xampp集成开发版本.但是mac下安装xampp失败,失败信息如下: Error starting "XAMPP" stack: fa ...

  2. iOS开发之Found a swap file by the name ".podfile.swp" owned by: Netban dated:...file name: ~N...

    Found a swap file by the name ".podfile.swp" owned by: Netban dated: Fri Mar 24 13:57:27 2 ...

  3. Springboot2.x 集成jsp

    1.添加pom依赖 <!--引入springboot 内嵌tomcat对jsp的解析包--> <dependency> <groupId>org.apache.to ...

  4. Nginx 学习专栏

    Nginx 入门学习教程 译:Centos7 编译安装Nginx 教程

  5. [HDFS Manual] CH8 HDFS Snapshots

    HDFS Snapshots HDFS Snapshots 1. 概述 1.1 Snapshottable目录 1.2 快照路径 2. 带快照的更新 3. 快照操作 3.1 管理操作 3.2 用户操作 ...

  6. css实现高度或者宽度不固定的div元素垂直左右居中

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. tf训练OTSU

    训练一个简单的回归网络 基础的函数如下: # coding=utf-8 import tensorflow as tf import numpy as np np.random.seed(0) # 卷 ...

  8. 【资料下载区】【iCore系列及其它模块相关文档】更新日期2017/07/24

    iCore系列双核心板原理图下载区 iCore双核心板原理图下载(注释版)iCore1s双核心板原理图下载iCore2双核心板原理图下载iCore3双核心板原理图下载iCore4双核心板原理图下载 i ...

  9. Java编程的逻辑 (93) - 函数式数据处理 (下)

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  10. 【Qt】信号和槽对值传递参数和引用传递参数的总结

    在同一个线程中 当信号和槽都在同一个线程中时,值传递参数和引用传递参数有区别: 值传递会复制对象:(测试时,打印传递前后的地址不同) 引用传递不会复制对象:(测试时,打印传递前后的地址相同) 不在同一 ...