0. 前言

在上一篇中,我故意留下了查询的示范没讲。虽然说可以通过以下代码获取一个DataReader:

IDataReader reader = command.ExecuteReader();

然后通过reader一行一行的读取数据,但是我并不推荐这样使用。

在查询这一高频需求上,C#为之做了很多工作,提供了更多的选择。这里介绍一个查询的另一套写法。

1. 离线查询

C#在查询上提供了另一种机制,可以一次性从数据库把结果读取到网络缓存区中,直到使用的时候才加载到程序中。

在离线查询里最关键的三个接口或类:

  • IDataAdapter 一种适配器,用来获取数据并填充或更新DataSet
  • DataSet 表示数据在内存中的缓存
  • DataTable 表示内存中一个数据表

IDataAdapter用来提供数据,DataSet表示adapter读取的结果集,其中有一个DataTable集合表示执行的SQL查询结果。至于为什么是集合,是因为IDataAdapter允许运行多条查询语句。

好,让我们粗略浏览一下这个三个关键点的属性和方法:

IDataAdapter:

public int Fill (System.Data.DataSet dataSet);//将查询出来的结果填充到DataSet里

在C#内部,其实不允许推荐直接继承该接口,推荐继承DataAdapter类,该类规定了数据库Adapter在初始化的时候,必须提供一个可以访问的数据库连接和要执行的命令文本。

当然其部分实现类允许以属性的形式后赋值这两个关键内容。

DataSet:

public DataSet ();
public DataSet (string dataSetName);//指定数据集的名称
public System.Data.DataTableCollection Tables { get; }//获取包含在 DataSet 中的表的集合

DataSet有很多有用的方法,但是在今天我们只用关系这些就可以了。

其中Tables 引入了一个没有提到的类型,DataTableCollection。那么我们可以顺藤摸瓜,来看看里面有什么关键的内容:

public System.Data.DataTable this[int index] { get; }// 获取指定下标的DataTable
public System.Data.DataTable this[string name] { get; }//获取具有指定名称的DataTable

可以看到提供了一种我们可以获取到里面的DataTable元素的索引访问方式。

DataTable :

public System.Data.DataSet DataSet { get; }//获取此表所属的 DataSet。
public System.Data.DataColumnCollection Columns { get; }//获取属于该表的列的集合
public System.Data.DataRowCollection Rows { get; }//获取属于该表的行的集合

又出现了两个新的类:DataColumnCollection、DataRowCollection。这是一种内部集合的实现类,功能类似于List,但又不等同于List。

我们大概看一下对我们有用的属性和方法:

DataColumnCollection:

public virtual int Count { get; }//获取集合中的元素总数
public System.Data.DataColumn this[int index] { get; }//从集合中获取位于指定索引位置的 DataColumn
public System.Data.DataColumn this[string name] { get; }//从具有指定名称的集合中获取 DataColumn。

DataRowCollection:

public override int Count { get; }
public System.Data.DataRow this[int index] { get; }// 获取索引处的行

嗯,好先到此为止。调转方向回到上个路口,重新来。让我们看看DataColumn和DataRow又有哪些值得我们现在关注的:

DataColumn:

public string ColumnName { get; set; }//获取或设置 DataColumnCollection 中的列的名称
public Type DataType { get; set; }//获取或设置存储在列中的数据的类型

DataRow:

public object this[System.Data.DataColumn column] { get; set; }//获取或设置指定 DataColumn 中存储的数据
public object this[int columnIndex] { get; set; }//获取或设置由索引指定的列中存储的数据
public object this[string columnName] { get; set; }//获取或设置由名称指定的列中存储的数据
public object[] ItemArray { get; set; }//通过数组获取或设置此行的所有值

到目前为止,离线查询的支持类和接口就介绍了个大概。那么我们看看如何进行一个离线查询吧

2.实践看看

以SQL Server数据库为例:

获取一个SqlDataAdapter,C#提供了四种方式获取:

public SqlDataAdapter ();//构造一个没有连接和命令的Adapter对象
public SqlDataAdapter (System.Data.SqlClient.SqlCommand selectCommand);// 指定一个查询命令
public SqlDataAdapter (string selectCommandText, System.Data.SqlClient.SqlConnection selectConnection);//指定查询命令,和连接
public SqlDataAdapter (string selectCommandText, string selectConnectionString);//指定查询命令和连接字符串

引用命名空间:

using System.Data;
using System.Data.SqlClient;

那么,我们先构造一个Adapter:

var connectStr = "Data Source=.;Initial Catalog=Old;Integrated Security=True";
var sql = "select * from Area_PostCode";
var adapter = new SqlDataAdapter(sql, connectStr);

然后创建一个用于保存数据的DataSet,并把数据填充进去:

DataSet set = new DataSet();
adapter.Fill(set);

然后可以看到这个set中的数据应该是这样的:

上图是在VS中的调试模式中,可以看到

根据上图我们大概可以猜测一下DataTable内部的数据结构,或者C#让我们理解的结构是什么。

其中DataColumn对应着图中列,ColumnName就是图 所示的列名。而DataRow就是行,ItemArray则是一行行数据。

这样一来,显然就比直接使用IDataReader访问数据要方便很多。

依据上例:

我们试着获取一下第三行的Province列值,如果觉得这个表述别扭的话,看一下我的写法,就知道我为什么这么表示了。

var table = set.Tables[0];// 先拿到第一个表
var value = table.Rows[2]["Province"];

这是一种蚂蚁搬家式的读取数据方式。C#为DataTable提供了一个扩展方法:

public static EnumerableRowCollection<DataRow> AsEnumerable(this DataTable source);

将表格转换成可枚举的DataRow集合。

所以我们可以用foreach循环来遍历DataTable。

3. 未完待续

在这一节简单介绍了一下ADO.NET的离线查询支持。当我们能从数据库中获取到DataTable的时候,我们就能通过这个做出更多的事情来。下一章我将带领大家结合之前介绍的反射,实现一个简单的ORM工具类。

更多内容烦请关注我的博客《高先生小屋》

C# 数据操作系列 - 3. ADO.NET 离线查询的更多相关文章

  1. C# 数据操作系列 - 2. ADO.NET操作

    0.前言 在上一篇中初略的介绍了一下SQL的基本写法,这一篇开始我们正式步入C#操作数据库的范围.通过这一系列的内容,我想大家能对于数据库交互有了一定的认识和基础.闲话不多说,先给大家介绍一个C#操作 ...

  2. C# 数据操作系列 - 16 SqlSugar 完结篇

    0. 前言 前一篇我们详细的介绍了SqlSugar的增删改查,那些已经满足我们在日常工程开发中的使用了.但是还有一点点在开发中并不常用,但是却非常有用的方法.接下来让我们一起来看看还有哪些有意思的内容 ...

  3. C# 数据操作系列 - 6 EF Core 配置映射关系

    0. 前言 在<C# 数据操作系列 - 5. EF Core 入门>篇中,我们简单的通过两个类演示了一下EF增删改查等功能.细心的小伙伴可能看了生成的DDL SQL 语句,在里面发现了些端 ...

  4. C# 数据操作系列 - 8. EF Core的增删改查

    0.前言 到目前为止,我们看了一下如何声明EF Core的初步使用,也整体的看了下EF Core的映射关系配置以及导航属性的配置. 这一篇,我带大家分享一下,我在工作中需要的EF Core的用法. 1 ...

  5. C# 数据操作系列 - 12 NHibernate的增删改查

    0. 前言 上一篇<C# 数据操作系列 - 11 NHibernate 配置和结构介绍> 介绍了Nhibernate里的配置内容.这一篇将带领大家了解一下如何使用NHIbernate.之前 ...

  6. C# 数据操作系列 - 15 SqlSugar 增删改查详解

    0. 前言 继上一篇,以及上上篇,我们对SqlSugar有了一个大概的认识,但是这并不完美,因为那些都是理论知识,无法描述我们工程开发中实际情况.而这一篇,将带领小伙伴们一起试着写一个能在工程中使用的 ...

  7. C# 数据操作系列 - 19 FreeSql 入坑介绍

    0. 前言 前几天FreeSql的作者向我推荐了FreeSql框架,想让我帮忙写个文章介绍一下.嗯,想不到我也能带个货了.哈哈,开个玩笑-看了下觉得设计的挺有意思的,所以就谢了这篇文章. 简单介绍一下 ...

  8. C# 数据操作系列 - 0. 序言

    0. 前言 在上一个系列中,我们初步浏览了一下C#的基础知识.这句话的意思就是C#基础知识系列完结了,撒花.当然,并不是因为C#已经讲完了.正是因为我们轻轻地叩开了那扇门,才能看到门后面那瑰丽的世界. ...

  9. C# 数据操作系列 - 1. SQL基础操作

    0.前言 前篇介绍了一些数据库的基本概念和以及一些常见的数据库,让我们对数据库有了一个初步的认识.这一篇我们将继续为C#数据操作的基础填上一个空白-SQL语句. SQL(Structured Quer ...

随机推荐

  1. day23作业

    # 作业: # 1.把登录与注册的密码都换成密文形式 info = {"tom":"202cb962ac59075b964b07152d234b70"} def ...

  2. 实战 | 将Apache Hudi数据集写入阿里云OSS

    1. 引入 云上对象存储的廉价让不少公司将其作为主要的存储方案,而Hudi作为数据湖解决方案,支持对象存储也是必不可少.之前AWS EMR已经内置集成Hudi,也意味着可以在S3上无缝使用Hudi.当 ...

  3. Kettle7.1创建资源库,资源库颜色灰色,没有Connect按钮解决办法

    我们在官网下载的Ketlle7.1工具,在本地运行时会发现标题中提到的问题:工具-资源库里面的按钮都是灰色的,无法点击.查找Connect整个页面找了个遍,也没有找到. 于是乎开始百度.谷歌的搜索啊. ...

  4. vim的常用指令

    vim的常用指令如下: 光标运动: h,j , k, l (上/下/左/右) 删除字符: x 删除行 : dd 模式退出 : Esc,Insert(或者i) 退出编辑器 : q 强制退出不保存: q! ...

  5. IIS WebDAV安全配置

    本文为转载,原文地址:http://www.2cto.com/article/201307/228165.html IIS WebDAV安全配置 2013-07-16 12:13:00 作者:瞌睡龙收 ...

  6. ajaxReturn案例

    请查看:http://www.cnblogs.com/bushe/p/4625097.html 不用自己写json格式啦,直接拿这个用就可以啦

  7. unset变量释放内存不起作用

    unset()函数只能在变量值占用内存空间超过256字节时才会释放内存空间. 只有当指向该变量的所有变量(如引用变量)都被销毁后,才会释放内存.

  8. CodeForces 674C Levels and Regions

    #include<bits/stdc++.h> using namespace std; const int maxn=2e5+5; int N,K,head,tair; int q[ma ...

  9. 飞机大战-面向对象-pygame

    飞机大战 最近学习了python的面向对象,对面向对象的理解不是很深刻. 面向对象是数据和函数的'打包整理',将相关数据和处理数据的方法集中在一个地方,方便使用和管理. 本着学习的目的,在网上找了这个 ...

  10. 【Linux网络基础】 DNS:介绍、作用、解析原理

    1. DNS是什么?   DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去+·记住能够被机器直接读 ...