在上一篇中,我故意留下了查询的示范没讲。虽说能够经过如下代码获取一个DataReader:sql
IDataReader reader = command.ExecuteReader();
而后经过reader一行一行的读取数据,可是我并不推荐这样使用。数据库
在查询这一高频需求上,C#为之作了不少工做,提供了更多的选择。这里介绍一个查询的另外一套写法。c#
C#在查询上提供了另外一种机制,能够一次性从数据库把结果读取到网络缓存区中,直到使用的时候才加载到程序中。数组
在离线查询里最关键的三个接口或类:缓存
IDataAdapter用来提供数据,DataSet表示adapter读取的结果集,其中有一个DataTable集合表示执行的SQL查询结果。至于为何是集合,是由于IDataAdapter容许运行多条查询语句。网络
好,让咱们粗略浏览一下这个三个关键点的属性和方法:数据结构
IDataAdapter:ide
public int Fill (System.Data.DataSet dataSet);//将查询出来的结果填充到DataSet里
在C#内部,其实不容许推荐直接继承该接口,推荐继承DataAdapter类,该类规定了数据库Adapter在初始化的时候,必须提供一个能够访问的数据库链接和要执行的命令文本。工具
固然其部分实现类容许以属性的形式后赋值这两个关键内容。this
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; }//经过数组获取或设置此行的全部值
到目前为止,离线查询的支持类和接口就介绍了个大概。那么咱们看看如何进行一个离线查询吧
以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。
在这一节简单介绍了一下ADO.NET的离线查询支持。当咱们能从数据库中获取到DataTable的时候,咱们就能经过这个作出更多的事情来。下一章我将带领你们结合以前介绍的反射,实现一个简单的ORM工具类。
更多内容烦请关注个人博客《高先生小屋》