当前位置: 移动技术网 > IT编程>开发语言>c# > C# 数据操作系列 - 3. ADO.NET 离线查询

C# 数据操作系列 - 3. ADO.NET 离线查询

2020年05月12日  | 移动技术网IT编程  | 我要评论

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中的数据应该是这样的:

image-20200512004118597

上图是在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工具类。

更多内容烦请关注

file

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网