用vs2005可以直接在项目中生成dataset,并且可以直接在dataset的设计界面编辑sql语句。我现在的问题是,如果用系统设计界面生成的TableAdapter。就无法再使用原来的事务处理方法啦。原来的事务处理是这样SqlTransaction   t   =   sqlConnection.BeginTransaction();   
  sqlDataAdapter1.UpdateCommand.Transaction   =   t;   
  sqlDataAdapter1.InsertCommand.Transaction   =   t;   
  sqlDataAdapter1.DeleteCommand.Transaction   =   t;   
  sqlDataAdapter1.Update(dataSet1);   
    
    
  if(正确)   
  {   
  t.Commit();   
  }   
  else   
  {   
  t.Rollback();   
  }如果还用这种方式,系统会提示:无法将类型“System.Data.OleDb.OleDbTransaction”隐式转换为“System.Data.SqlClient.SqlTransaction”我在网上找到啦另一种很方便的方法,引用System.Transactions
using (System.Transactions.TransactionScope updateTransaction =new System.Transactions.TransactionScope())
            {
                ta.InsertName("1456789", "456", "456");
                ta1.InsertName1("1456145614561456", "456", "456");                updateTransaction.Complete();
              
            }
但是它也报错,貌似说,该方法只能用于分布式的事务管理,是这样的吗?我想,vs05既然有啦方便的dataset设计,那么一定也有更先进的事务处理方法吧。这里请教各位大侠啦。

解决方案 »

  1.   

    用2005DataSet事务确和2003不同,在App_Code中要写一个类,如下代码:
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Data.SqlClient;/// <summary>
    /// Tra 的摘要说明
    /// </summary>
    namespace DataSet1TableAdapters
    {
        public partial class STUDENTTableAdapter
        {
            private SqlTransaction _transaction;
            private SqlTransaction Transaction
            {
                get
                {
                    return this._transaction;
                }
                set
                {
                    this._transaction = value;
                }
            }        public void BeginTransaction()
            {
                // Open the connection, if needed            
                if (this.Connection.State != ConnectionState.Open)
                    this.Connection.Open();            // Create the transaction and assign it to the Transaction property
                this.Transaction = this.Connection.BeginTransaction();            // Attach the transaction to the Adapters
                foreach (SqlCommand command in this.CommandCollection)
                {
                    command.Transaction = this.Transaction;
                }            this.Adapter.UpdateCommand.Transaction = this.Transaction;
                this.Adapter.DeleteCommand.Transaction = this.Transaction;
                this.Adapter.InsertCommand.Transaction = this.Transaction;
            }        public void CommitTransaction()
            {
                // Commit the transaction
                this.Transaction.Commit();            // Close the connection
                this.Connection.Close();
            }        public void RollbackTransaction()
            {
                // Rollback the transaction
                this.Transaction.Rollback();            // Close the connection
                this.Connection.Close();
            }
        }
    }
    红色的和粗体的要注意和自己的项目对应,粗体对应的是你在DataDet1中创建的,我这里创建的是名为STUDENT,
    所有的事务的sql语句写在STUDENTTableAdapterx下,调用:STUDENTTableAdapter _STUDENT = new STUDENTTableAdapter();
    _STUDENT.BeginTransaction();//启动事务
    try
    {
          _STUDENT.Insert.....
         _STUDENT.Update....
         ............
         _STUDENT.CommitTransaction();
    }
    catch
    {
        ...........
        ...........
        _STUDENT.RollbackTransaction();
    ............
    }
      

  2.   

    通过dataset的管理界面可以直接编辑每张表的TableAdapter。根据需要生成很多增删改查的方法。我们可以实例化TableAdapter后调用这些方法。现在的问题是这些表的adapter没有UpdateCommand.Transaction 这样的属性。
    而且连接Connection也是由系统管理的,所以this.Transaction = this.Connection.BeginTransaction(); 根本无法实现。也就是说通过vs的dataset管理界面生成的TableAdapter类,现在看来是无法用传统的方法进行事物管理的。那么我相信它一定有一套自己管理事物的方法。但是我不知道该怎么做。
      

  3.   

    为啦说明更详细,我把dataset的生成过程写下来。传统的dataset一般是这样
                   //SQL命令对象
    SqlCommand selcmd = new SqlCommand();
    selcmd.Connection = conn;
    selcmd.CommandText ="SELECT RegionID, RegionDescription FROM Region";
    //SQ适配器命令执行对象
    SqlDataAdapter da = new SqlDataAdapter();
    //命令对象的SelectCommand方法只能执行select语句
    da.SelectCommand = selcmd;
    //记录集,用于接收记录
    DataSet ds = new DataSet();
    // SQL命令执行对象执行sql命令。将返回记录写入记录集。
    da.Fill(ds);
    // 填充了数据就可以关闭连接了
    conn.Close();adapter的方法,是我们写在程序中的。而使用vs管理的dataset。每张表都会自动生成两个类1 dataset类 2 adapters类。
    创建过程如下
    1  我们先新建一个数据源
    2  工程中新建一个数据集DataSet
    3  在数据集DataSet的设计视图上将数据源中需要使用的表拖入。这样我们就得到啦一个独立的数据访问层了。这个数据集DataSet包含了两个类。一个类是数据模型类,它提供啦数据表的实体类。另一个是Adapters类,它提供了数据库的访问方法。
    4  使用时我们要先实例化这两个类,值得注意的是它们不在同一个命名空间下,DataSet位于当前工程命名空间下,所以它可以直接实例化。而Adapters在当前命名空间的子空间下的[DataSet1Table]Adapters中。每一张表对应一个Adapters类。
    使用时代码如下:
               //实例化数据集,注意不是dataset,他是vs自动生成的。
                aopDataSetTable ds = new aopDataSetTable ();
                        //实例化orders表的Adapter类
                OrdersTableAdapter ot = new OrdersTableAdapter();
                //取数据库数据填充入数据集orders表中。
                ot.Fill(ds.Orders);
                //数据集绑定数据网格
                dataGridView1.DataSource = ds.Orders;
    我们可以发现vs生成的dataset与传统的dataset相比要简单很多。但是它的属性与传统的也不一样,所以不能使用传统的事物管理。但是要怎么来管理事物呢?
      

  4.   

    SqlTransaction   换成DbTransaction,试一下。
      

  5.   

    试过啦,不行。
    由于sqlConnection是由系统管理的自动生成管理的,我们可以通过这样调用extendTableAdapter ta=new extendTableAdapter();
    ta.Connection.BeginTransaction().Begin();但是实际调用的时候系统会提示Connection已经关闭。。崩溃中。。
      

  6.   

    我也是通过DataSet来创建DataAdapter,
    我发在2楼的一个类就是来调用事务的,楼主问题出在那里?
      

  7.   

    首先谢谢koukoujiayi的回复。
    问题是:
    this.Connection报错。
    这个类自己没有声明,也没有继承。这个this.Connection来自哪里呢?
      

  8.   

    不太清楚你的Connection错误!!
    我是用ObjiectDataSource,事实上不用连接控件在页面上的cs文件上写也可以,
    作为测试事务是否有效,然后再使用连接控件,
    参考了一个外国人写的程序,都用ObjiectDataSource,一般不直接连DataSet中的DataAdapter,
    而是在App_code文件夹下写一个类,作为中间层,事务写在中间层的类里.
    的确从2003的传统编写方法,转到2005的那编写方法,是有个困惑过程,
    望你不要崩溃.....
      

  9.   

    ObjiectDataSource?
    这个东东我还没有用过。这是一个控件,还是什么呢?
      

  10.   

    你是指的,在绑定数据源时选择“对象”那个方法吗?那个好像要自己写业务类,不用DataAdapter, 
      

  11.   

    ObjiectDataSource数据源控件,可以绑定到中间层(也就是你说的业务类),
    对简单的那些不要处理的可直接绑盯到DataSet中的DataAdapter对象!!