摘要
ADO.NET有兩個核心組件:基于連接的Data Provider組件以及基于非連接的DataSet組件。基于連接的Data Provider組件常用于實時地從數(shù)據(jù)庫中檢索數(shù)據(jù)。而基于非連接的DataSet,似乎與數(shù)據(jù)庫沒有直接聯(lián)系,僅僅用于在本地內(nèi)存中存儲Data Provider提供的數(shù)據(jù)表或集合。這一切似乎很微妙,此時,你是否在想:這兩大組件是如何聯(lián)系在一起的呢?或許,通過閱讀本文會或多或少解除你的一些疑惑呢!
1. 認識DataAdapter
前面我所講的對象中,譬如Connection對象,Command對象以及DataReader對象,這些對象均屬于Data Provider的一部分,而且都是基于連接的。擁有強大功能的它們,讓你可以很輕松地連接一個特定的數(shù)據(jù)源,執(zhí)行SQL語句,檢索只讀的數(shù)據(jù)流等等。這些基于連接的對象都對應(yīng)于特定的數(shù)據(jù)源。換句話說,對于不同的數(shù)據(jù)源,我們需要找到對應(yīng)的數(shù)據(jù)庫提供程序(Data Provider)來匹配他們。當(dāng)然,你也不必為此感到困惑和緊張,在前面我已經(jīng)講得很詳細了。或許,以目前我們所學(xué)的知識,對于操作數(shù)據(jù)源以及檢索數(shù)據(jù)完全沒有什么問題呢!但是,這并沒有發(fā)揮出ADO.NET的優(yōu)勢。如果,每次我們檢索數(shù)據(jù)庫中的表或者行都需要連接一次數(shù)據(jù)庫,那么性能和效率是十分低下的。實際上,ADO.NET提供了基于非連接的核心組件:DataSet。DataSet組件讓我們可以很愉快地在內(nèi)存中操作以表為中心的數(shù)據(jù)集合,就好比操作數(shù)據(jù)庫中的表一樣。這是多么讓人興奮和激動啊!
不知道大家有沒有想過這樣一個問題(反正我是想了):既然DataSet是基于非連接的(不需要連接數(shù)據(jù)庫),那么它存儲的數(shù)據(jù)集合是從哪里來呢?實際上,很多時候,它的數(shù)據(jù)還是來自于數(shù)據(jù)庫。Oh!這似乎有點自相矛盾了!打個“不雅”的比喻:就好比沒有雞,那哪來的蛋呢?你不妨換個角度來思考問題!雖然,你沒有養(yǎng)雞,但是,你不是還可以從超市或者其他零售店買到雞蛋嗎?同理,盡管DataSet沒有直接連接數(shù)據(jù)庫,但是,ADO.NET早就為DataSet準備了一位非常謙虛友善的中介:DataApdater。DataApater數(shù)據(jù)適配器,就是這樣一個對象:它為外部數(shù)據(jù)源與本地DataSet集合架起了一座堅實的橋梁,將從外部數(shù)據(jù)源檢索到的數(shù)據(jù)合理正確的調(diào)配到本地的DataSet集合中。
2. DataAdapter的工作原理
要說DataAdapter是ADO.NET世界里最為復(fù)雜的部分,其實也不為過!但是,我們也不必驚慌。盡管DataAdater內(nèi)部實現(xiàn)機制較為復(fù)雜,但是提供開發(fā)人員的接口卻是異常的簡單。我們知道,DataApapter本質(zhì)上就是一個數(shù)據(jù)調(diào)配器。當(dāng)我們需要查詢數(shù)據(jù)時,它從數(shù)據(jù)庫檢索數(shù)據(jù),并填充要本地的DataSet或者DataTable中;當(dāng)我需要更新數(shù)據(jù)庫時,它將本地內(nèi)存的數(shù)據(jù)路由到數(shù)據(jù)庫,并執(zhí)行更新命令。下面我們以Customer表為例,來理解DataAdapter的工作原理。
我們可以知道,當(dāng)我查詢Customer信息,DataAdapter首先將構(gòu)造一個SelectCommand實例(本質(zhì)就一個Command對象),然后檢查是否打開連接,如果沒有打開連接則打開連接,緊接著調(diào)用DataReader接口檢索數(shù)據(jù),最后根據(jù)維護的映射關(guān)系,將檢索到得數(shù)據(jù)庫填充到本地的DataSet或者DataTable中。同理,我們需要更新數(shù)據(jù)源時,DataAdatper則將本地修改的數(shù)據(jù),跟據(jù)映射關(guān)系,構(gòu)造InsertCommand,UpdateCommnad,DeleteCommand對象,然后執(zhí)行相應(yīng)的命令。
之所以說,DataAdapter是最復(fù)雜的ADO.NET組件,是因為它是架構(gòu)在所有其他DataProvider對象之上的。Connection對象,DataReader對象,Paramter對象以及Command對象,都盡可能的為它服務(wù)。總體來說,DataAdapter主要有三大功能:
數(shù)據(jù)檢索:盡可能用最簡單的方法填充數(shù)據(jù)源到本地DataSet或者DataTable中。細致的說,DataAdapter用一個DataReader實例來檢索數(shù)據(jù),因此你必須提供一個Select查詢語句以及一個連接字符串。
數(shù)據(jù)更新:將本地修改的數(shù)據(jù)返回給外部的數(shù)據(jù)源相對來說稍微復(fù)雜一點。即使,從數(shù)據(jù)庫查詢數(shù)據(jù)時,我們僅僅只需要一條基本的Select語句,而更新數(shù)據(jù)庫則需要區(qū)分Insert,Update,Delete語句。
表或列名映射:維護本地DataSet表名和列名與外部數(shù)據(jù)源表名與列名的映射關(guān)系。
3. 說說DataAdapter的重要成員
作為.NET DataProvider對象成員之一,DataAdapter跟其他數(shù)據(jù)提供對象具有相似的特征:都是基于連接的,都繼承于基類,不同的數(shù)據(jù)源都對應(yīng)自己的派生版本。這樣理解的話,學(xué)習(xí)DataAdapter似乎簡單的多。DataAdapter的基類是DBDataAdapter,它的結(jié)構(gòu)如下:
public abstract class DbDataAdapter : DataAdapter,
IDbDataAdapter, IDataAdapter, ICloneable
從上面我們可以看到,DBDataAdapter是一個抽象基類,不能被實例化,并且繼承DataAdapter類,IDBDataApdater,IdataAdapter以及Icloneable接口。DataAdapter成員較多,必須掌握的有以下幾種:
SelectComand屬性:獲取或設(shè)置用于在數(shù)據(jù)源選擇記錄的命令。
UpdateCommand屬性:獲取或這只用于更新數(shù)據(jù)源中的記錄的命令。
DeleteCommand屬性:獲取或設(shè)置用于從數(shù)據(jù)源中刪除記錄的命令。
InsertCommand屬性:獲取或設(shè)置用于將新記錄插入數(shù)據(jù)源中的命令。
Fill方法:填充數(shù)據(jù)集。
Update方法:更新數(shù)據(jù)源。
4. 總結(jié)
本文我主要從"WHY"與"WHAT"的角度詳細講解了DataAdapter的工作原理以及主要作用。如果文章對園友們有幫助,希望能得到您的推薦和關(guān)注。您的肯定和支持是我繼續(xù)寫作的最大動力!