DataReader和DataAdapter的区别
SqlDataReader是一个向前的指针,本身并不包含数据,调用一次Read()方法它就向前到下一条记录,一个SqlDataReader必须单独占用一个打开的数据库连接。
在使用 SqlDataReader时,关联的 SqlConnection 正忙于为 SqlDataReader 服务,对 SqlConnection 无法执行任何其他操作。除非调用 SqlDataReader 的 Close 方法,否则会一直处于此状态。
SqlDataAdapter象一座桥梁,一头连起数据库表,一头连起一个 DataSet 或者 DataTable ,在把数据库中的数据填充到 DataSet 或 DataTable 后就可以“过河拆桥”,不用再连接到数据库,而可以直接从 DataSet 或 DataTable 中获取数据。
SqlDataAdapter提供了许多的方法,来方便我们对一些特定的数据集合进行操作比如,填充一个查询结果到 DataTable ,或 DataSet 中其实就是类似于:创建一个 SqlCommand 然后执行 "Select * from [Table]" 然后执行 ExcuteReader()方法 得到一个IDataReader对象然后逐行读取数据并存放到一个集合对象中(如DataTable)经过测试,如果有大量的数据操作最好是自己写 SqlCommand ,会比SqlDataAdapter操作数据库快很多
SqlDataReader只能读取数据库,而且所操作的表必须处于连接状态,但是要对数据库进行写操时,只能借助 SqlCommand 类,SqlDataAdapter 它建立在 SqlCommand 对象之上,它具有 SqlCommand 类的一切功能,能够将数据填充到 DataSet 对象中,而且不用再连接到数据库,而可以直接从 DataSet 或 DataTable 中获取数据。(因为它采用的无连接传输模式)
SqlDataReader对象可以从数据库中得到只读的、只能向前的数据流,还可以提高应用程序的性能,减少系统开销,同一时间只有一条行记录在内存中。
SqlDataAdapter对象可以自动打开和自动关闭数据库连接(不需人为管理),适配器的主要工作流程:SqlConnection 对象建立与数据源的连接,SqlDataAdapter 对象经由 SqlCommand 对象返回给SqlDataAdapter,最后将SqlDataAdapter对象加入到 DataSet 对象的 DataTables 对象中。
总结:
性能上:SqlDataReader一次只在内存中存储一行,减少了系统开销。优于SqlDataAdapter。
读取时:SqlDataReader需通过调用自身Read()方法循环读取数据到指定对象。而SqlDataAdapter可通过调用Fill()方法一次性填充数据到DataSet。还可将对 DataSet 所做的更改解析回数据源。
操作上:SqlDataReader需通过调用自身的Close()方法断开连接。而SqlDataAdapter可以读取完数据库后自动断开连接.
- var sql = "SELECT * FROM BOARD_VEHICLE_DAY_INFO WHERE PASSKEY='湘ALM2DA-2-2019年10月15日' ";
DataTable result = new DataTable();- //ExecuteReader
- using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
- {
- conn.Open();
- //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
- OracleCommand cmd = new OracleCommand(sql, conn);
- //创建查询的结果集,用另一个封装的方法,ExecuteReader
- OracleDataReader read = cmd.ExecuteReader();
- result.Load(read);
- }
- //OracleDataAdapter
- using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
- {
- conn.Open();
- //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
- OracleCommand cmd = new OracleCommand(sql, conn);
- OracleDataAdapter adapter = new OracleDataAdapter(cmd);
- adapter.Fill(result);
- }
使用20万条数据进行测试
- ExecuteReader耗时50秒,
- OracleDataAdapter耗时11秒
测试如下
- Stopwatch watch = Stopwatch.StartNew();
- watch.Start();
- List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
- List<BOARD_VEHICLE_DAY_INFOEntity> list1 = new List<BOARD_VEHICLE_DAY_INFOEntity>();
- List<BOARD_VEHICLE_DAY_INFOEntity> list2 = new List<BOARD_VEHICLE_DAY_INFOEntity>();
- List<BOARD_VEHICLE_DAY_INFOEntity> list3 = new List<BOARD_VEHICLE_DAY_INFOEntity>();
- Task wt1 = Task.Run(() =>
- {
- list1 = test1();
- list.AddRange(list1);
- });
- Task wt2 = Task.Run(() =>
- {
- list2 = test2();
- list.AddRange(list2);
- });
- Task wt3 = Task.Run(() =>
- {
- list3 = test3();
- list.AddRange(list3);
- });
- var wtasks = new Task[] { wt1, wt2, wt3 };
- Task.WaitAll(wtasks);
- watch.Stop();
- Console.WriteLine($"耗时:{watch.ElapsedMilliseconds},总数:{list.Count}");
- Console.ReadKey();
- static private List<BOARD_VEHICLE_DAY_INFOEntity> test1()
- {
- List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
- DataTable result = new DataTable();
- var sql = "SELECT * FROM BOARD_VEHICLE_DAY_INFO WHERE PASSKEY LIKE '豫%' ";
- //ExecuteReader
- using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
- {
- conn.Open();
- //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
- OracleCommand cmd = new OracleCommand(sql, conn);
- //创建查询的结果集,用另一个封装的方法,ExecuteReader
- //OracleDataReader read = cmd.ExecuteReader();
- //result.Load(read);
- OracleDataAdapter adapter = new OracleDataAdapter(cmd);
- adapter.Fill(result);
- conn.Close();
- list = ConvertToModel<BOARD_VEHICLE_DAY_INFOEntity>(result);
- }
- return list;
- }
- static private List<BOARD_VEHICLE_DAY_INFOEntity> test2()
- {
- List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
- DataTable result = new DataTable();
- var sql = "SELECT * FROM BOARD_VEHICLE_DAY_INFO WHERE PASSKEY LIKE '湘%' ";
- //ExecuteReader
- using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
- {
- conn.Open();
- //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
- OracleCommand cmd = new OracleCommand(sql, conn);
- //创建查询的结果集,用另一个封装的方法,ExecuteReader
- //OracleDataReader read = cmd.ExecuteReader();
- //result.Load(read);
- OracleDataAdapter adapter = new OracleDataAdapter(cmd);
- adapter.Fill(result);
- conn.Close();
- list = ConvertToModel<BOARD_VEHICLE_DAY_INFOEntity>(result);
- }
- return list;
- }
- static private List<BOARD_VEHICLE_DAY_INFOEntity> test3()
- {
- List<BOARD_VEHICLE_DAY_INFOEntity> list = new List<BOARD_VEHICLE_DAY_INFOEntity>();
- DataTable result = new DataTable();
- var sql = "SELECT * FROM BOARD_VEHICLE_DAY_INFO WHERE PASSKEY LIKE '鄂%' ";
- //ExecuteReader
- using (OracleConnection conn = new OracleConnection("Data Source=zhzepp;User Id=jxlx;Password=citms;"))
- {
- conn.Open();
- //创建命令对象,前面一个表示执行的语句,后面一个表示执行语句需要连接的数据库
- OracleCommand cmd = new OracleCommand(sql, conn);
- //创建查询的结果集,用另一个封装的方法,ExecuteReader
- //OracleDataReader read = cmd.ExecuteReader();
- //result.Load(read);
- OracleDataAdapter adapter = new OracleDataAdapter(cmd);
- adapter.Fill(result);
- conn.Close();
- list = ConvertToModel<BOARD_VEHICLE_DAY_INFOEntity>(result);
- }
- return list;
- }
- /// <summary>
- /// 将DataTable数据源转换成实体类
- /// </summary>
- public static List<T> ConvertToModel<T>(DataTable dt) where T : new()
- {
- List<T> ts = new List<T>();// 定义集合
- foreach (DataRow dr in dt.Rows)
- {
- T t = new T();
- PropertyInfo[] propertys = t.GetType().GetProperties();// 获得此模型的公共属性
- foreach (PropertyInfo pi in propertys)
- {
- if (dt.Columns.Contains(pi.Name))
- {
- if (!pi.CanWrite) continue;
- var value = dr[pi.Name];
- try
- {
- if (value != DBNull.Value && value != null && value.ToString() != "")
- {
- if (pi.PropertyType.FullName.ToUpper().Contains("DECIMAL"))
- {
- pi.SetValue(t, decimal.Parse(value.ToString()), null);
- }
- else if (pi.PropertyType.FullName.ToUpper().Contains("DOUBLE"))
- {
- pi.SetValue(t, double.Parse(value.ToString()), null);
- }
- else if (pi.PropertyType.FullName.ToUpper().Contains("INT32"))
- {
- pi.SetValue(t, int.Parse(value.ToString()), null);
- }
- else if (pi.PropertyType.FullName.ToUpper().Contains("INT16"))
- {
- pi.SetValue(t, short.Parse(value.ToString()), null);
- }
- else
- pi.SetValue(t, value, null);
- }
- }
- catch (Exception ex)
- {
- //throw ex;
- }
- }
- }
- ts.Add(t);
- }
- return ts;
- }
DataReader和DataAdapter的区别的更多相关文章
- ADO.NET DataReader和DataAdapter的区别
SqlDataReader是一个向前的指针,本身并不包含数据,调用一次 Read() 方法它就向前到下一条记录,一个SqlDataReader必须单独占用一个打开的数据库连接. 在使用 SqlData ...
- Data Base sqlServer DataReader与DataSet的区别
sqlServer DataReader与DataSet的区别 从以下这几个方面比较: 1.与数据库连接: DataReader:面向连接,只读,只进,只能向前读,读完数据就断开连接: DataS ...
- Winform开发之ADO.NET对象Connection、Command、DataReader、DataAdapter、DataSet和DataTable简介
ADO.NET技术主要包括Connection.Command.DataReader.DataAdapter.DataSet和DataTable等6个对象,下面对这6个对象进行简单的介绍:(1)Con ...
- sqlServer DataReader与DataSet的区别
sqlServer DataReader与DataSet的区别 从以下这几个方面比较: 1.与数据库连接: DataReader:面向连接,只读,只进,只能向前读,读完数据就断开连接: DataS ...
- DataReader 和 DataSet 的区别
摘自:http://www.cnblogs.com/zhjjNo1/archive/2009/08/26/1554420.html 第一种解释 DataReader和DataSet最大的区别在于,Da ...
- C# 之 DataReader 和 DataSet 的区别
本文转载自:http://www.cnblogs.com/xinaixia/p/4920630.html 1. 获取数据的方式[1]DataReader 为在线操作数据, DataReader会一直占 ...
- DataReader和DataSet的区别以及使用
DataReader和DataSet这两个对象都可以将检索的关系数据存储在内存中.它们在功能使用方面非常相似,但是它们不可以相互替换. 主要区别如表所示: DataReader DataSet 数 ...
- Sql Server + ADO.NET
MsSql-http://www.cnblogs.com/zhangwei595806165/archive/2012/02/23/2364746.html 协议:Shared Memory :效率最 ...
- datareader 和dataset 区别
ADO.NET2.0提供了两个用于检索关系数据的对象:DataSet和DataReader.并且这两个对象都可以将检索的关系数据存储在内存中.在软件开发过程中经常用到这两个控件,由于这两个控件在使用和 ...
随机推荐
- cssdiv设置高宽百分比不起作用的问题
div等元素设置宽高百分比都是基于包含他的块级对象的百分比高度,所以必须先设置包含它的块级对象高度与宽度,但是光设置body是不起作用的,必须同时设置html和body. 要使用百分比设置div宽 ...
- Latin-1字符集
ISO Latin-1字符集是Unicode字符集的一个子集,对应于IE4+中Unicode字符指令表的前256个条目.下面表格中详细提供了每个字符及字符的十进制编码和HTML已命名实体.其中Unic ...
- spring boot 整合mapreduce运行的ClassNotFoundException
问题 一个wordcount运行总是报错 java.lang.RuntimeException: java.lang.ClassNotFoundException: Class com.hadoop. ...
- Ubuntu配置Python开发环境(PyCharm、Tensorflow)
安装JDK: https://www.cnblogs.com/wanghuixi/p/9837229.html 安装Anaconda: 安装PyCharm: https://www.cnblogs.c ...
- input和button 高度不一致问题
原因是 input和button的高度计算不一样, input高度不包括border. button高度包括border. 解决方法: 1.box-sizing:border-box: 2.borde ...
- 使用IDEA导入一个Maven风格的SSM项目
转自: 方法一: (我用的这种,导入的方法 File->New->Project from existing sources)(同理,important也是一样的) https://how ...
- redhat7.6 DNS配置正向解析
1.安装DNS服务 yum install bind yum install bind-chroot 安装完的配置文件/etc/named.conf 启动systemctl start named.s ...
- vector的使用-Hdu 4841
圆桌问题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submis ...
- 「NOI2006」最大获利
「NOI2006」最大获利 传送门 最小割. 对于每一组用户群 \(A_i, B_i, C_i\) ,连边 $S \to A_i, S \to B_i, $ 容量为成本,还有 \(i \to T\) ...
- Python 中命令行参数解析工具 docopt 安装和应用
什么是 docopt? 1.docopt 是一种 Python 编写的命令行执行脚本的交互语言. 它是一种语言! 它是一种语言! 它是一种语言! 2.使用这种语言可以在自己的脚本中,添加一些规则限制. ...