天天看點

C# 資料操作系列 - 3. ADO.NET 離線查詢

C# 資料操作系列 - 3. ADO.NET 離線查詢

  1. 前言

    在上一篇中,我故意留下了查詢的示範沒講。雖然說可以通過以下代碼擷取一個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.Rows2;

這是一種螞蟻搬家式的讀取資料方式。C#為DataTable提供了一個擴充方法:

public static EnumerableRowCollection AsEnumerable(this DataTable source);

将表格轉換成可枚舉的DataRow集合。

是以我們可以用foreach循環來周遊DataTable。

  1. 未完待續

    在這一節簡單介紹了一下ADO.NET的離線查詢支援。當我們能從資料庫中擷取到DataTable的時候,我們就能通過這個做出更多的事情來。下一章我将帶領大家結合之前介紹的反射,實作一個簡單的ORM工具類。

原文位址

https://www.cnblogs.com/c7jie/p/12874317.html