如何获取变更过的DataTable中的记录?

  某次MSDN上看到一个客户需要获取所有变更过的行记录,如何处理这个问题这里简单说一下。

  DataTable看做是一个物理表的内存式存储,每一个DataRow都有一个属性叫做RowState。因此任意一行中某一个字段发生改变,那么整个DataRow的RowState也就发生了改变。RowState是一个枚举,其中包含5个内容:

      1)Detached:未被附加(一般刚创建的DataRow,或者已经被Remove或者RemoveAt,或者Delete之后调用过AcceptChanges方法的行,或者是WinForm控件DataGridView默认设置下最后那个永远也留出的空行……都被自动设置该状态)。

      2)Added:刚添加的新行。

      3)Deleted:刚被删除的行(注意:只是从内存表中删除,物理数据表中尚未删除此时你无法直接去访问该行的某个字段的内容!)。

       4)Modified:刚被修改的行。

       5)Unchanged:原来的行。

  DataTable批量通过内部遍历这些行的RowState,然后借助DataAdapter的CRUD方法根据这些State调用不同的语句批量更新到真实数据表中。

  如果要取消可以调用DataTable的RejectChanges方法确认从内存表中删除才调用AcceptChanges方法

  通过DataRow的RowState最多只能判断哪行被修改,那么调用不同的语句如何进行更新呢?比如说我要更新一行,肯定使用update……where语句,where后面的条件是一个旧值,set是一个新值,如何获取旧值呢?

  .NET中的DataColumn有一个属性叫做DataRowVersion,这个属性有4个:

      1)Current:当前数值(DataRowState=Deleted时候无效)。

      2)Original:原来数值(DataRowState=Added或者Unchanged时候无效)。

      3)Proposed:建议数值(仅在DataRowState=Detached的时候有效)。

      3)Default:默认数值(DataRowState=Added,Modified或者Unchanged时,等于Current;如果DataRowState=Deleted,等于Original;如果DataRowState=Detached,那么等于Proposed)。该属性可以自动调整,你吃不准哪一行的属性,一律可以使用这个属性获取特定字段的内容。

      根据这个法则,我们再结合微软DataTable的GetChanges方法轻易可以获取做了任意变更的源数据和现实数据,具体可以参考这个代码(C#):

DataTable dt = new DataTable();
            dt.Columns.Add("Id");
            for (int i = 1; i < 11; i++)
            {
                dt.Rows.Add(i);
            }
            dt.AcceptChanges();
            //添加第十一行
            dt.Rows.Add(11);
            //修改第二行
            dt.Rows[1][0] = 21;
            //删除第一行
            dt.Rows[0].Delete();
            //检索情况
            DataTable cdt = dt.GetChanges();
            for (int i = 0; i <cdt.Rows.Count; i++)
            {
                if (cdt.Rows[i].RowState == DataRowState.Deleted)
                {
                    Console.WriteLine("删除的行索引{0},原来数值是{1}",i,cdt.Rows[i][0,DataRowVersion.Original]);
                }
                else if (cdt.Rows[i].RowState == DataRowState.Modified)
                {
                    Console.WriteLine("修改的行索引{0},原来数值是{1},现在的新数值{2}", i, cdt.Rows[i][0, DataRowVersion.Original],cdt.Rows[i][0,DataRowVersion.Current]);
                }
                else if (cdt.Rows[i].RowState == DataRowState.Added)
                {
                    Console.WriteLine("新添加行索引{0},数值是{1}", i, cdt.Rows[i][0, DataRowVersion.Current]);
                }
            }
posted @ 2013-04-16 17:52  Serviceboy  阅读(840)  评论(0编辑  收藏  举报