以下部份转自: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. Windows上的字符转换之CP_ACP和CP_OEMCP

    原文地址:http://blog.sina.com.cn/s/blog_53c1950a010158mw.html Windows API函数MultiByteToWideChar用于多字节编码字符串 ...

  2. webstorm intelliJ IDEA phpstorm 设置鼠标滚动改变字体大小

    control+shift+A功能可以搜索对应功能,把mouse:Change font size(Zoom) ...的按钮打开,然后就可以通过 ctrl+鼠标上下滚动调节字体大小

  3. Android application捕获崩溃异常

    Java代码 .收集所有 avtivity 用于彻底退出应用 .捕获崩溃异常,保存错误日志,并重启应用 , intent, , restartIntent); // 关闭当前应用 finishAllA ...

  4. iframe中video没有全屏按钮

    HTML内联框架元素 <iframe> iframe默认不允许全屏, 如果内嵌了video那么控制条上将不显示全屏按钮, 通过添加allowfullscreen属性可以开启全屏功能. mo ...

  5. 采石厂管理系统V3.0版本上线(采石厂车辆出入管理系统,石厂开票系统)

    新版系统包含老版所有功能,软件基础功能请点击查看<采石管理系统,采石厂车辆出入管理系统> 新增功能点 近期对采石厂管理系统进行了升级和完善,系统更加灵活好用,应用场景更加广泛.主要更新一下 ...

  6. Mac下的Chrome或Safari访问跨域设置,MBP上使用模拟器Simulator.app或iphone+Safari调试网页

    Mac下的Chrome或Safari访问跨域设置: mac下终端启动Chrome $ open -a Google\ Chrome --args --disable-web-security 或 /A ...

  7. Linux内核同步

    Linux内核剖析 之 内核同步 主要内容 1.内核请求何时以交错(interleave)的方式执行以及交错程度如何. 2.内核所实现的基本同步机制. 3.通常情况下如何使用内核提供的同步机制. 内核 ...

  8. .NET CORE控制器里的方法取传参的坑

    把以前的ASP.NET MVC的项目改成用.NET CORE来写,写好了部署上去了,结果问题一大堆,今天慢慢检查了一下,发现一个大坑: 写控制器里的方法接收参数数都是直接写在控制器的方法参数里的,如: ...

  9. webview调起浏览器

    调起浏览器 url = "intent://" + url +"#Intent;scheme=http;action=android.intent.action.VIEW ...

  10. vim常用技巧

    # vim常用技巧 ## 行操作------------------------------ 行首 0- 行尾 $- 第一个非空字符 ^ ## 列编辑模式----------------------- ...