最近在项目中,做一个采集模块,用到了 dbcommandbuilder 来做数据的批量更新,本来似乎是很简单的事,但是由于业务,由于设计模式的引入,使得这个简单的事多了些耐人寻味的地方。呵呵,接下来将一一做介绍。
一、业务背景:
每天采集的数据的条目是固定的,比如说油田A下面有W1,W2,W3 这 3 口井,那么某个用户管理这个油田,就负责要录入这3口井的数据。
二、实现要求:
界面上有一个时间选择框,还有一个油田选择列表,然后一个查询按钮。当用户进入系统后, 会根据默认选择的时间来初始化录入界面的数据,如果当天没有数据,那么要把这三口井都显示出来,因为没有数据,所以这三行都用绿色,如果有一口井有数据了,那么这一行就是白色。格式如下:
三、实现方法:
要达到上面的效果,首先要写一个 SQL 获取当天的数据放入到 TAll,然后另外一个SQL获取当天没有录入的数据放入到Ttemp,然后将 Ttemp 中的数据加到 TAll 中,然后绑定到数据展示控件。
在编辑完毕之后,点击保存按钮,此时执行 dbdataadapter 的 update 方法即可。
我在数据访问层中的代码如下:
1 public int UpdateTable(DataTable dt, string selectString)
2 {
3 icommand.CommandText = selectString;
4 ida.SelectCommand = this.icommand;
5
6 //当更换 selectcommand 时,要调用该方法,否则 builder 会保留先前自动生成的 INSERT、UPDATE、DELETE 语句
7 //2010-11-05 00:23:15
8 this.builder.RefreshSchema( );
9 this.builder.DataAdapter = ida;
10 return ida.Update(dt);
11 }
对该方法的几项说明:
1. 一个 dbcommandbuilder 对象只能和一个 dbdataadapter 关联,dbcommandbuilder 会根据dbdataadapter 绑定的 selectcommand 来自动生成相应的 insert, update, delete
2. selectcommand 的 commandtext 必须包含主键字段
3. 若为 dbdataadapter 更换 selectcommand ,则需要先执行 dbcommandbuilder 对象的 RefreshSchema 方法,然后再绑定其 dataadapter 属性。
4. 使用单例模式时,要特别注意,上面代码中的第8行不能少。否则 dbcommandbuilder 会保存上次执行的更新的 dbcommand ,不能实现其他表的更新,通俗点说,就是,如果先执行A表的批量更新后,再执行B表的批量更新时会报错。