惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
D
Docker
Blog — PlanetScale
Blog — PlanetScale
罗磊的独立博客
美团技术团队
V
V2EX
Last Week in AI
Last Week in AI
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Microsoft Security Blog
Microsoft Security Blog
Microsoft Azure Blog
Microsoft Azure Blog
人人都是产品经理
人人都是产品经理
M
MIT News - Artificial intelligence
P
Proofpoint News Feed
B
Blog RSS Feed
博客园_首页
B
Blog
博客园 - 叶小钗
I
InfoQ
WordPress大学
WordPress大学
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
About on SuperTechFans
The GitHub Blog
The GitHub Blog
The Register - Security
The Register - Security
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
Latest news
Latest news
W
WeLiveSecurity
T
The Exploit Database - CXSecurity.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
aimingoo的专栏
aimingoo的专栏
小众软件
小众软件
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
C
CXSECURITY Database RSS Feed - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
N
News and Events Feed by Topic
S
Secure Thoughts
The Hacker News
The Hacker News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News

博客园 - MainIsUsed

svg札记 rabbitmq 小记 nfc相关 MI卡UID oracle9i导入导出命令 (转)C++中指针和引用的区别 .net下的office开发(visio对象) 【转】C#中的非安全编程(key:unsafe,fixed) Oracle中UTL_FILE包的UTL_FILE.FOPEN用法 c# 获取串口设备的输入(unsigned char *和 char*) URL字符串编码 笔记HTML - MainIsUsed - 博客园 .net导出为powerpoint的一些参考代码 关于ClickOnce 发布过程中的错误:要求高版本的CAPICOM.dll Oracle EXTRACT()函数与to_char() 函数 c#接口使用方法 - MainIsUsed - 博客园 在 WinForm 中完整支持在多级目录中保存的 ASP.NET (转) - MainIsUsed (转)实现基于事件通知的.Net套接字 (转)什么是套接字(Socket)?
关于DataTable的GetChanges()方法
MainIsUsed · 2009-06-06 · via 博客园 - MainIsUsed

之前有几个朋友都提到过GetChanges方法在调用的时候获取不到修改的数据或者获取到的是不对的数据,于是就和朋友一起讨论,也做了DEMO测试,

但是最后还是不了了之。当然结果是朋友换了方法,而自己也没去多在意这个方法,因为自己一直都不用他。

今天又有朋友提到这个问题,于是就花了点时间多了解了一下。当然还是自己写DEMO做测试,最后原因还是没找出来,这多少和项目本身是有点关系的。

问题没解决,但是还是总结了点东西,这里放上DEMO和一些个人见解。本人抛砖,如果引不了玉,也很欢迎各位砸砖。

通常情况下,GetChanges方法是能获取到表自上次调用AcceptChanges以来的所发生的所有更改的,包括增加、修改、删除(删除以空行表示)。

获取不到的情况估计就要根据不同的情况进行调试了,程序一个细微的操作,比如焦点变化、鼠标操作等都有可能引起相关事件的调用执行。

而这些事件都可能影响表GetChanges方法获取数据的正确性,到这里,我都是在猜测……。

下面来讲讲GetChanges方法大概的执行过程。.NET提供给我们的仅仅是GetChanges方法而已,而GetChanges到底是如何运作的,我们不知道,

因为.NET把这些操作都封装了。.NET公开给我们可供我们调用的就是我们在开发环境里可以点出来的,而执行这些可调用方法的另一些内部

internal等,后面将会介绍)方法或者属性等等,我们只能通过调试的时候查看或者通过反编译器来查看。

首先我们可以通过反编译工具来查看GetChanges方法的执行内容,这里我用的是Reflector,因为他显示出的源代码就是我们的逻辑代码。

在发现自己对某些东西模糊不清的时候,就应该试着去搞清楚,所以后面会整理一些反编译和反汇编的东西,因为突然想起IL代码。

这里就不多说了,自己都不是很清楚的东西怕误导别人,特别是概念这东西。可以肯定的是,虽然Reflector有反汇编的功能,

但这里是反编译源代码……

因为测试的是DataTable的GetChanges方法,所以我们就首先得找到DataTable所属的DLL,

“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll”如果默认安装没有改动的话,

位置应该就是这里了。这里的测试环境是.NET 2005。到这里,觉得自己有点啰嗦,但是因为是写给新手区的,

所以就啰嗦点吧。Reflector的使用还是很简单的,这里就不做介绍了,我们只要一直点+号找到DataTable然后再

找到GetChanges然后就可以找到我们需要的东西了。最终的结果是:

Code

首先我们注意返回值,是我们需要的DataTable,方法最后返回的是table2,而table2的前身是table,而table在

获取的时候判断了row.oldRecord != row.newRecord

newRecordoldRecord 是我们在开发环境里无法调用了,因为他们被封装了。查看Reflector我们看到

internal int oldRecord;
说明他是程序集内部使用的,所以我们无法调用。但是我们可以查看,Reflector里或者在开发调试的时候。
GetChanges会通过判断数据行的Record来获取变更过的数据行。既然Record是对于数据行的,数据行有集合
那么record也会有集合来对应,而那个集合就是

Code


后面会通过调试来说明getChanges判断RECORD的大概过程
运行DEMO的时候,在获取到表的更改的时候,我们可以在更改获取的时候设置一个断点,
进入断点的时候监视方式更改的表。注意是更改的源表,而不是获取到的已经更改的表。如图

 
因为要查看的是非公开的成员,所以我们这里选最后一个“非公共成员”进行查看。进入非公共成员后选择recordmanager
进入recordManager后我们就发现了ROWS集合,这里集合的大小是以128为单位递增的。如果行集合小于128则大小为128,
如果大于128小于256则大小为256,以此类推。
进入ROWS集合
点开随便一个ROWS,我们就能查看ROWS的ROWSTATE、olerecord和newrecord了。
RowState记录的是的状态,有修改,增加,删除(如果行被删除,这里会显示为NULL,但是查看对象还是能看到rowstate的值)
这里来讲讲最重要的oldrecord和newrecord的真正用处。
拿修改来说:
如果原本的数据是3行
列1    列2
1      11
2      22
3      33
 
修改第二行
列1    列2
 
1      11
2      44
3      33
 这时候rows集合里的存储是这样的
1      11 newrecord=1,oldrecord=1
2      22 newrecord=2,oldrecord=2
3      33 newrecord=3,oldrecord=3
2      44 newrecord=4,oldrecord=2
这里的第四行就是我们更改的行,大家应该能看出规律吧,如果再修改第三行的话
则会再添加一行,如果把33改为55,则新添加到记录会是
3      55 newrecord=5,oldrecord=3
 
到此,上完色不知道怎么去色了……
上面只是说明getchanges的内部机理,希望不会越描越黑。
 
DEMO