dataset中有个datatable,表中有几条记录(比如10条),这几条记录通过事务提交到数据库,也就是要么全部写入要么全部不写入,现在的问题是当其中某条记录保存出错后(比如第5条),数据库中已经保存的4条记录已经回滚,但dataset中这4条记录却标记为已提交,也就是当对第5条记录修改正确重新保存时,系统只保存了从第5条开始往后的6条记录,前面的4条记录却没有保存,也就是前面4条记录在第一次保存的时候虽然数据库中已经回滚,但在dataset中并没有回滚,郁闷之极

解决方案 »

  1.   


    回滚后对dt如何操作啊,dt没有回滚方法的呀
      

  2.   

    RejectChanges和AcceptChanges是不是你想要的。DataRow有以下几种状态
     Added 该行已添加到 DataRowCollection 中,AcceptChanges 尚未调用。  
     Deleted 该行已通过 DataRow 的 Delete 方法被删除。  
     Detached 该行已被创建,但不属于任何 DataRowCollection。DataRow 在以下情况下立即处于此状态:创建之后添加到集合中之前;或从集合中移除之后。  
     Modified 该行已被修改,AcceptChanges 尚未调用。  
     Unchanged 该行自上次调用 AcceptChanges 以来尚未更改。  还是不太了解lz想要什么
      

  3.   

    我的意思是dataset中的数据提交的时候,前面几行数据成功写入数据库后,系统自动调用了acceptchanges,但后面的行发生错误后,前面已经acceptchanges的行就没法回到原先的行状态了,也就是数据库回滚了,但dataset中的行状态并没有回滚
      

  4.   

     系统会自动调用acceptChanges吗?这个我没试过,不好说,不过如果真是这样,你可以考虑现将DataSet Clone一份
      

  5.   

    clone一份可以解决,但有另外一个问题,就是clone中的主键和原先的主键无法对应,也就没法合并
    比如原先表中有个id字段为自动编号,值为1,2,3,4,5,把这个dataset clone一下,然后用这个clone的dataset提交到数据库后,数据库对此字段重新编号,变成31,32,33,34,35,这样clone中的id字段的值就和原先的不一样了,没法合并回去了
      

  6.   

    ds.Tables[0].RejectChanges();//回滚dataset
      

  7.   


    如果你入库都成功了,就把clone那份抛弃掉,用原始那份不就结了
      

  8.   


    成功后必须从clone那份中把新的id号复制到原始的那份中,否则原始的那份和数据库是不一致的
      

  9.   


    acceptchanges后再调用rejectchanges是没有用的
      

  10.   

    不是,你要提交事务后再调用acceptchanges吧?没有用数据库事务?
      

  11.   

    主要看你更新部分的代码是怎么写的,问题在表的行状态上。
    还是用copy()吧,不用colne
      

  12.   


    用的数据库事务,acceptchanges没有在程序中调用,是系统自动调用的,因为查看行状态发现,只要每写入成功一行,那一行的状态就acceptchanges了,而不管所在的事务有没有最后完成
      

  13.   

    修改已经更新行的状态For i As Integer = 0 To table.Rows.Count - 1
                    If table.Rows(i).RowState = DataRowState.Unchanged Then
                        table.Rows(i).SetAdded()
                    End If
                Next
      

  14.   

    啊!没有发现,我用的Command.Parameters,你使用Command.Parameters试试?
      

  15.   

    楼主可以试一下这里的处理方式,下面是代码片段,完整例子看这里的文章,
    http://blog.csdn.net/zhzuo/archive/2004/08/06/67037.aspxpublic void UpdateCustomerOrdersWithTransaction(DataSet ds){     SqlTransaction trans = null;     try     {            _conn.Open();         trans = _conn.BeginTransaction();         _customerDataAdapter.DeleteCommand.Transaction = trans;         _customerDataAdapter.InsertCommand.Transaction = trans;         _customerDataAdapter.UpdateCommand.Transaction = trans;         _orderDataAdapter.DeleteCommand.Transaction = trans;         _orderDataAdapter.InsertCommand.Transaction = trans;         _orderDataAdapter.UpdateCommand.Transaction = trans;     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.Added));                   _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.Added));     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.ModifiedCurrent));     _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.ModifiedCurrent));     _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.Deleted));     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.Deleted));           trans.Commit();     }     catch(Exception ex)     {         trans.Rollback();         throw new Exception("更新数据出错",ex);     }     finally     {         if(_conn.State != ConnectionState.Closed)              _conn.Close();     }}
      

  16.   


    关键是在Orders提交失败时,如何使Customers的RowState回复到Update前的状态?
      

  17.   

    1.更具行状态获得CmdText,和parameters和parameterValues;
    2.iCommnad.Parameters.Add(new OleDbParameter(parameters[i],parameterValues[i]));//ODBC或OLEDB连接的话就这样
    3.iCommnad.Transaction=iTrans;
      iCommnad.ExecuteNonQuery();
    过程大致如上