本文实例讲述了C#获取变更过的DataTable记录的实现方法,是一个非常实用的功能!具体实现方法如下:

首先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]);
}
}

最新文章

  1. 《转载》Spring MVC之@RequestParam @RequestBody @RequestHeader 等详解
  2. oss文件删除策略
  3. ComboSelect 下拉筛选
  4. UICollectionView的使用小记录和一些说明
  5. Discuz! 6.x/7.x 全局变量防御绕过导致命令执行
  6. java_queue
  7. CentOS查看端口是否被占用
  8. [UI列表]LoopScrollRect无限滑动不卡顿
  9. RxJS操作符(一)
  10. mybatis源码-解析配置文件(四-1)之配置文件Mapper解析(cache)
  11. 什么是渲染目标(render target)&& 渲染到纹理(Render To Texture, RTT)详解
  12. Oracle 非归档--归档操作流程
  13. kbmMW均衡负载与容灾(2)(转载红鱼儿)
  14. 用原生js实现ajax
  15. 清理和关闭多余的Windows 7系统服务
  16. 开始Hibernate介绍
  17. eclipse启动报错 Problems occurred when invoking code from plug-in: &quot;org.eclipse.jface&quot;
  18. 生成对抗网络(Generative Adversarial Network)阅读笔记
  19. BZOJ3529: [Sdoi2014]数表(莫比乌斯反演 树状数组)
  20. GlusterFS + lagstash + elasticsearch + kibana 3 + redis日志收集存储系统部署 01

热门文章

  1. error while loading shared libraries: libg2o_core.so: cannot open shared object file: No such file or directory解决方法
  2. IDEA15 下运行Scala遇到问题以及解决办法
  3. 第八节,Opencv的基本使用------存取图像、视频功能、简单信息标注工具
  4. vim配置(使用Vundle)
  5. Saltstack自动化操作记录(2)-配置使用
  6. rsync3.1.3的编译安装和常用操作
  7. python结合pyvmomi批量关闭vmware虚拟机
  8. 【原创】大叔问题定位分享(14)Kylin频繁OOM问题
  9. vue路由守卫(全局守卫)
  10. 【python】实用的logging封装