在上一篇中,我故意留下了查詢的示範沒講。雖說能夠經過如下代碼獲取一個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工具類。
更多內容煩請關注個人博客《高先生小屋》