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 = https://www.cnblogs.com/c7jie/p/table.Rows[2]["Province"];
這是一種螞蟻搬家式的讀取資料方式,C#為DataTable提供了一個擴展方法:
public static EnumerableRowCollection<DataRow> AsEnumerable(this DataTable source);
將表格轉換成可列舉的DataRow集合,
所以我們可以用foreach回圈來遍歷DataTable,
3. 未完待續
在這一節簡單介紹了一下ADO.NET的離線查詢支持,當我們能從資料庫中獲取到DataTable的時候,我們就能通過這個做出更多的事情來,下一章我將帶領大家結合之前介紹的反射,實作一個簡單的ORM工具類,
更多內容煩請關注我的博客《高先生小屋》

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/40649.html
標籤:C#
