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的区别的更多相关文章

  1. ADO.NET DataReader和DataAdapter的区别

    SqlDataReader是一个向前的指针,本身并不包含数据,调用一次 Read() 方法它就向前到下一条记录,一个SqlDataReader必须单独占用一个打开的数据库连接. 在使用 SqlData ...

  2. Data Base sqlServer DataReader与DataSet的区别

    sqlServer   DataReader与DataSet的区别 从以下这几个方面比较: 1.与数据库连接: DataReader:面向连接,只读,只进,只能向前读,读完数据就断开连接: DataS ...

  3. Winform开发之ADO.NET对象Connection、Command、DataReader、DataAdapter、DataSet和DataTable简介

    ADO.NET技术主要包括Connection.Command.DataReader.DataAdapter.DataSet和DataTable等6个对象,下面对这6个对象进行简单的介绍:(1)Con ...

  4. sqlServer DataReader与DataSet的区别

    sqlServer   DataReader与DataSet的区别 从以下这几个方面比较: 1.与数据库连接: DataReader:面向连接,只读,只进,只能向前读,读完数据就断开连接: DataS ...

  5. DataReader 和 DataSet 的区别

    摘自:http://www.cnblogs.com/zhjjNo1/archive/2009/08/26/1554420.html 第一种解释 DataReader和DataSet最大的区别在于,Da ...

  6. C# 之 DataReader 和 DataSet 的区别

    本文转载自:http://www.cnblogs.com/xinaixia/p/4920630.html 1. 获取数据的方式[1]DataReader 为在线操作数据, DataReader会一直占 ...

  7. DataReader和DataSet的区别以及使用

    DataReader和DataSet这两个对象都可以将检索的关系数据存储在内存中.它们在功能使用方面非常相似,但是它们不可以相互替换. 主要区别如表所示:   DataReader DataSet 数 ...

  8. Sql Server + ADO.NET

    MsSql-http://www.cnblogs.com/zhangwei595806165/archive/2012/02/23/2364746.html 协议:Shared Memory :效率最 ...

  9. datareader 和dataset 区别

    ADO.NET2.0提供了两个用于检索关系数据的对象:DataSet和DataReader.并且这两个对象都可以将检索的关系数据存储在内存中.在软件开发过程中经常用到这两个控件,由于这两个控件在使用和 ...

随机推荐

  1. 【转】使用普通用户执行docker

    原文:https://www.cnblogs.com/klvchen/p/9098745.html CentOS 版本 7.4,Docker 版本 docker-1.13 及以下 ll /var/ru ...

  2. 第七届蓝桥杯javaB组真题解析-四平方和(第八题)

    题目 /* 四平方和 四平方和定理,又称为拉格朗日定理: 每个正整数都可以表示为至多4个正整数的平方和. 如果把0包括进去,就正好可以表示为4个数的平方和. 比如: 5 = 0^2 + 0^2 + 1 ...

  3. Mysql基本用法-存储引擎-03

    看到存储引擎这个地方感到很多细节比较陌生,所以总结小记一些 为了适应各种不同的运行环境,MYSQL提供了多种不同的存储引擎(Storage Engine ),在应用程序开发这个层面上,开发者可以根据不 ...

  4. django 模版标签笔记

    一.模板变量笔记:1.在模版中使用变量,需要将变量放到‘{{}}’中.'{{ 变量 }}'2.如果想访问对象的属性,可以通过'对象.属性名'的方式访问3.如果想要访问一个字典的key对应的value, ...

  5. HTML常用标签效果展示

    HTML常用标签效果展示 一.文本效果 段落1---收到了开发建设看来得更加快乐圣诞节福利肯定是减肥的路上苏里科夫就是打开了飞机都是风口浪尖上的疯狂了大煞风景圣诞快乐的索科洛夫几点上课了关键是低空掠过 ...

  6. 微信小程序加密解密 C# 以及 填充无效,无法被移除错误的解决方案 Padding is invalid and cannot be removed

    解密加密源码 using System; using System.Security.Cryptography; using System.Text; namespace Wechat { publi ...

  7. SpringData学习笔记一

    Spring Data : 介绍: Spring 的一个子项目.用于简化数据库访问,支持NoSQL 和 关系数据存储.其主要目标是使数据库的访问变得方便快捷. SpringData 项目所支持 NoS ...

  8. win10程序无法正常启动0xc0000142

    office用的好好的,今天一早打开电脑,突然就打不开了.显示如图: 我个人猜测可能还是昨天更新其他软件的时候导致的,有个软件更新后,让我重启,当时因为忙,就没有重启.今天一开机,就发现office用 ...

  9. HDU1029 简单DP

    "OK, you are not too bad, em... But you can never pass the next test." feng5166 says. &quo ...

  10. 日常使用SqlServer的笔记

    表操作 查表大小 sp_spaceused 表名 修改表名 ALTER TABLE table RENAME TO NEW_TABLE_NAME; 修改列名 不支持 ALTER TABLE table ...