.Net中DataAdapter批量插入和更新数据总结

简介:

前言

  前段时间一直在忙着项目上线,在做项目的同时遇到了一些之前不曾碰到的问题,因为没有经验,只能从网上找一些相关的解决方案,但是网上提供的资料实在是太杂,有的根本不能用,耗时又耗力。

  我希望把我这段时间遇到的问题记录下来,去帮助那些当时和我一样“饥渴”的人,以减少时间成本,大家放心,遇到的这些问题提供的解决方案都是经过我们测试,现在正在用的,基本上没什么问题。有什么问题,大家也可以进行探讨,因为问题很多,有些记不起来了,我只能写些可以记起来的分享给大家。

  插一句,就是大家在搜问题的时候,尽量用关键字,不是你搜不到问题的答案,而是你搜问题的方式有问题,而且尽量用google,大家用过就知道为什么了,看不懂的有google翻译。

批量插入

  我们在.net操作大数据的时候,有时候会遇到大量数据插入的情况,遇到这种方式,我们遇到最笨的方式是forearch插入,很少的数据是可以,但是几千条,几万条就死掉了,这种方式性能很差。既然如此,微软不可能没有好的解决方案的,这就是DataAdapter,我贴下批量插入的:

复制代码
     public static bool MultiInsertData(DataSet ds, string Columns, string tableName)
        {
            using (OracleConnection connection = new OracleConnection(connectionString))
            {
                string SQLString = string.Format("select {0} from {1} where rownum=0", Columns, tableName);
                using (OracleCommand cmd = new OracleCommand(SQLString, connection))
                {
                    try
                    {
                        connection.Open();
                        OracleDataAdapter myDataAdapter = new OracleDataAdapter();
                        myDataAdapter.SelectCommand = new OracleCommand(SQLString, connection);
                        myDataAdapter.UpdateBatchSize = 0;
                        OracleCommandBuilder custCB = new OracleCommandBuilder(myDataAdapter);
                        DataTable dt = ds.Tables[0].Copy();
                        DataTable dtTemp = dt.Clone();

                        int times = 0;
                        for (int count = 0; count < dt.Rows.Count; times++)
                        {
                            for (int i = 0; i < 400 && 400 * times + i < dt.Rows.Count; i++, count++)
                            {
                                dtTemp.Rows.Add(dt.Rows[count].ItemArray);
                            }
                            myDataAdapter.Update(dtTemp);
                            dtTemp.Rows.Clear();
                        }

                        dt.Dispose();
                        dtTemp.Dispose();
                        myDataAdapter.Dispose();
                        return true;
                    }
                    catch (System.Data.OracleClient.OracleException E)
                    {
                        connection.Close();
                        return false;
                    }
                }
            }
        }
复制代码

  大家都是搞编程的,一看就明白,我就简单的说下,参数ds是要更新的数据集,Columns是要插入的列表,TableName是要插入的表名,这里需要强调的一点是,插入数据集里的表的字段和类型必须和数据库那边一致,这点重要,要不然插入会报错。

  这里还有加了个分段插入,就是那个for,每400条插入一次,这样可以避免插入的数据太大,会发生超时异常。

  我做项目的时候遇到这种情况是:有些数据是要先保存到本地,比如SqlLite,然后再上传到数据库。

  这里给大家个建议,如果用到wcf,就在传输前对数据集进行压缩,然后到服务端再解压下,这样传输速度会很快。有时间给大家提供压缩的方法。

批量更新

  批量更新和批量插入差不多的逻辑,我先贴下代码:

复制代码
        public static bool MultiUpdateData(DataTable data, string Columns, string tableName)
        {
            using (OracleConnection connection = new OracleConnection(connectionString))
            {
                string SQLString = string.Format("select {0} from {1} where rownum=0", Columns, tableName);
                using (OracleCommand cmd = new OracleCommand(SQLString, connection))
                {
                    try
                    {
                        connection.Open();
                        OracleDataAdapter myDataAdapter = new OracleDataAdapter();
                        myDataAdapter.SelectCommand = new OracleCommand(SQLString, connection);
                        OracleCommandBuilder custCB = new OracleCommandBuilder(myDataAdapter);
                        custCB.ConflictOption = ConflictOption.OverwriteChanges;
                        custCB.SetAllValues = true;
                        foreach (DataRow dr in data.Rows)
                        {
                            if (dr.RowState == DataRowState.Unchanged)
                                dr.SetModified();
                        }
                        myDataAdapter.Update(data);
                        data.AcceptChanges();
                        myDataAdapter.Dispose();
                        return true;
                    }
                    catch (System.Data.OracleClient.OracleException E)
                    {
                        connection.Close();
                        return false;
                    }
                }
            }
        }
复制代码

  大家看代码发现和上面插入是差不多的,但是有几点注意的地方我说下,数据集行的状态RowState必须是Modified状态,不是的话需要设置一下,还有就是更新的数据集中必须包含主键,没有的话就会报错。

  重要的一点就是data.AcceptChanges();这句代码,如果注释掉的话,虽然myDataAdapter.Update(data);这段代码更新了,但是数据库那边还是不行的,我的理解是这样:Adapter本身是适配器的意思,适配器是连接两个物体之间的桥梁,就像协议一样,两边都通过才可以完成整个过程。data.AcceptChanges();的意思是应用数据集的更改,我测试过在数据集传输之前应用更新,也是可以更新到数据库的,可能就是dr.SetModified();这段代码在控制吧,如果数据库中的数据在数据集中发生变化,就会生成相应的Uodate,执行更新,这些都是我的猜测,底层的东西我不是很了解,这也是我欠缺的地方,等项目上线完一定要恶补下。

  批量更新我应用的场景是:datagridview绑定查询的数据,对数据进行修改,然后批量更新到数据库。

  希望可以帮到需要帮助的朋友。。。

 


本文转自田园里的蟋蟀博客园博客,原文链接:http://www.cnblogs.com/xishuai/p/3471508.html,如需转载请自行联系原作者

相关文章
|
5月前
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
mvc.net分页查询案例——DLL数据访问层(HouseDLL.cs)
|
2月前
|
开发框架 .NET 数据库连接
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
|
3月前
|
开发框架 JSON 前端开发
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
|
2月前
|
开发框架 前端开发 算法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
|
5月前
|
存储 测试技术 计算机视觉
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据
|
5月前
|
SQL 数据库
使用ADO.NET查询和操作数据
使用ADO.NET查询和操作数据
|
5月前
|
SQL 开发框架 .NET
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
ASP.NET WEB+EntityFramework数据持久化——考核练习库——1、用户管理系统(考点:查询列表、增加、删除)
112 0
|
5月前
|
Oracle 关系型数据库 数据管理
.NET医院检验系统LIS源码,使用了oracle数据库,保证数据的隔离和安全性
LIS系统实现了实验室人力资源管理、标本管理、日常事务管理、网络管理、检验数据管理(采集、传输、处理、输出、发布)、报表管理过程的自动化,使实验室的操作人员和管理者从繁杂的手工劳作中解放出来,提高了检验人员的工作效率和效益,降低了劳动成本和差错发生率。
|
12月前
|
前端开发 JavaScript
.net core 前端传递参数有值 后端接收到的数据却是null
1、问题分析 在做接口测试时,偶然出现了前端输出有值,但是后端断点调试时却出现接收参数总是为null的情况 2、解决办法 前端打印log,看前端的每一个传值的数据类型,与后端请求参数类进行认真的一一比对 小技巧: ① 直接打印调用接口的传参值的数据类型,例如 console.log(type of this.form.name) --string console.log(type of this.form.age) --number 打印的数据类型与后端接口的参数类比对,查出不对应的类型 ② 关于非必填的值,默认传值可能出现空字符串(' ')、NaN值(Not a Number
234 0
|
关系型数据库 MySQL
使用ADO.NET 实体数据模型连接MySql
使用ADO.NET 实体数据模型连接MySql
206 0

相关课程

更多
下一篇
无影云桌面