DataSet更新到数据库总结

本文介绍了一种使用DataSet将数据批量更新到数据库的方法,包括生成表结构、创建命令、添加新行及更新数据的过程,并讨论了处理主键冲突的策略。

DataSet更新到数据库总结

最近在工作中再次遇到了将DataSet中的数据全部插入数据库的情况。这种情况以前也处理过,很久没用又忘记了,今天特别总结一下这种情况的处理方式。


首先,用Select语句查询需要插入数据的表,用Top 1查一行就够了,这个是为了给SqlDataAdapter生成表的架构用的。

复制代码

1  string  strSql  =   " Select * from TableNeedToUpdate "   ;  

2  SqlDataAdapter da  =     new    SqlDataAdapter(strSql, SqlConn);  

3  DataSet ds  =   new  DataSet();  

4  da.Fill(ds);  

5  // 设置主键  

6  ds.Tables[ 0 ].PrimaryKey  =   new  DataColumn[] { ds.Tables[ 0 ].Columns[ 0 ] }; 

复制代码


其次,用SqlCommandBuilder为SqlDataAdapter生成用于添加、删除、更新的Command。 
复制代码

1  SqlCommandBuilder cmdb  =    new  SqlCommandBuilder(da);  

2  da.InsertCommand  =  cmdb.GetInsertCommand();  

3  da.UpdateCommand  =  cmdb.GetUpdateCommand();  

4  da.DeleteCommand  =  cmdb.GetDeleteCommand();

复制代码




然后,如果根据要插入的数据生成新行。 

复制代码

1  foreach  (DataRow dr  in  dtNew.Rows)  

2  {

3        DataRow drNew  =  ds.Tables[ 0 ].NewRow();

4        drNew.ItemArray  =  dr.ItemArray;

5        ds.Tables[ 0 ].Rows.Add(drNew);

6  }

复制代码



最后,用da.Update(ds),即可将数据一次性插入数据库中。



对于一些特殊情况,比如新插入数据跟原表中数据主键冲突的情况,则要多费点周折。正常情况下,这种情况应该是用更新来处理,而不是用插入。但有的时候,更新比较麻烦的时候,也可以用先删除,后插入的方式来处理。



举个例子,也就是我这一次处理的情况。我需要定时从一个系统读取数据写入另外一个系统。数据源的数据是不定时更新的,没有更新标识,每次读取的时候,根本不知道哪些数据是新增的或是修改过的(当然也可以通过主键来进行判断,但是比较麻烦)。这个时候,不能直接将这些数据写入目的数据库,因为可能会有主键重复的问题,所以需要先删除目的数据库中的数据,然后将新数据一次性全部写入数据库。



这个流程说起来非常清楚,问题在于如何删除目的数据库旧数据。我之前采取的方法是用Table.Rows.Clear()方法: 
复制代码

1  ds.Tables[ 0 ].Rows.Clear();  

2  da.Update(ds);  

3  ds.AcceptChanges();   

复制代码



这样操作之后,插入新数据,会出现“主键重复”的错误。而只能采用Table.Rows.Delete()方法:
复制代码

1  for ( int  i  =   0 ; i  <  ds.Tables[ 0 ].Rows.Count; i ++ )

2  {

3      ds.Tables[ 0 ].Rows[ 0 ].Delete();            

4  }             

5  da.Update(ds);             

6  ds.AcceptChanges(); 

复制代码

 究其原因,是跟SqlDataAdapter的处理机制有关系的。SqlDataAdapter.Update()是根据DataSet中DataRow的状态标记来处理的,比如我们用DataSet.Tables[0].Rows.Add(drNew)来添加一行时,drNew会有一个状态Added,执行SqlDataAdapter.Update()时,会根据这个状态对数据行进行处理,对应的,更新的数据行会有Updated状态,删除的数据行会有Deleted状态。



对于Rows.Clear()方法,是将数据从数据表中清除,它不会为被删除的行添加标记,所以在执行SqlDataAdapter.Update()时就不会首先将表中的数据删除,从而导致主键重复的错误。而对于Rows.Delete(),它不会直接把数据行删除,而是加上Deleted标记,所以可以在Update的时候正确的将数据删除。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值