剖析 .Net 下的數據訪問層技術(二)

其它<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

      結束ADO.NET剖析前,不得不提提DataReaderDataSet間的兄弟

之爭。

      就作者所看過的資料,幾乎所有的都建議實際情況具體分析,剩下

很少很少的則全憑個人習慣決定。

      在學習ADO.NET時,作者也是抱着這樣的想法,並反覆牢記資料

上總結的那些條款(就像當年學習GOF 23條時那樣,幾乎可以倒背如

流了J),想到終有一日也可在ADO.NET下大展神威了。

 

      可惜現實不隨人願,連續做了幾個項目,無論規模大小,竟然全部

採用了DataSet解決方案!

      此時,再回頭看看學習ADO.NET時打開最爲頻繁的PetShop項目,

兩相一比較,這纔看出些許端倪。

 

      簡單的說,PetShop採用瞭如下這種“曲線救國”的方式來實現數據

交換:

 

      DataReader獲取數據 => 創建數據實體類 => 根據字段類型填充

據實體類 => 將數據實體添加到列表類中(僅針對返回超過一條數據的

場合)

      (補充:採用數據實體類或者集合類可以比較方便的實現Cache Manament

而普通的DataReader由於其數據讀取方式限制,無法滿足這種需求)

 

      這個過程與DataAdapter.Fill() 所所產生的效果大同小異,只不過,

Fill() DataAdpater自動創建DataReader去獲取數據,之後創建

DataTable(相當於數據實體類),並根據字段類型填充DataTable,當然

,如果可能返回多條記錄,DataTable完全可以處理,就沒必要去實現列

表操作了。

      可能讀者馬上產生了疑問:既然如此,PetShop中爲何還需要數據實

體類呢?

      這其中還是有一些差別的。

      首先,數據實體類是輕量級的structure,一般僅包含數據字段,沒有

什麼操作方法,這比DataTable或者DataRow還是有一些性能上的優勢

(在數據量不大時可以忽略不計);另一方面,數據實體類的操作相對

簡單,不需要開發人員具備任何ADO.NET知識(其實就DataTable

說,這也不算什麼問題),點點屬性就可以了。

      不過,根據作者的實踐來看,這兩方面似乎還不足以使人轉而使用

DataReader方案,理由列舉如下:

     

(1)    對於數據量較大的場合,可以採用分批讀取的方式,這有點類似DataGrid的數據分頁效果;

 

(2)    對於簡單的數據,實體類還能應付,一旦涉及關聯數據,就只能另外撰寫方法了。而所有這些,在DataSet中是非常容易處理的(對於企業級應用,大部分情況都需要處理比較複雜的數據);

 

(3)    DataTable“天生”就支持數據集合操作,這樣的特性比“集合+實體”的混合模式(PetShop)更容易控制,也更自然;

 

(4)    實體類在聲明時需要確定所有數據類型,當進行數據填充時,就需要DataReader再次關注實體所對應的數據類型,不能有絲毫差錯!在這方面,DataTable就顯得非常方便,操作時只需要一次類型關注即可;

 

(5)    DataSet解決方案可以非常方便的支持序列化操作(如:RemotingWebServices),同時,與XML的關係更是親密無比,這對於和其它系統的交互來說也是至關重要的。

 

分析過一些技術和方案,相信讀者朋友已有一些體會。值此收官之際,如果非要在這裏提供一個“綜上所述”,那作者的建議就非常明確:

 

在企業級應用開發中,儘可能的採用DataSetDataTable / DataView+ Cache Management解決方案!

 

其它開發中,只在如下4種情況才考慮使用DataReader(就作者經驗來說,大部分使用DataReader都屬第種情況):

 

(1)    對資源要求比較苛刻的場合,這裏的資源主要指內存和數據庫連接;

 

(2)    希望在讀取數據庫返回結果集時作自定義處理,例如:在讀取一條記錄後立刻終止處理,或者在讀取時作計算操作。

(提示:這種情況類似於XML中的SAXSimple API for XML)技術,無需一次性讀入所有XML數據即可進行操作;相反的,DOMDocument Object Model)則要求必須裝載所有XML數據後才能開始操作(MSXML4.0已開始允許只讀取XML文檔部分數據即可開始操作,這是後話)!

 

(3)       只希望得到返回記錄數或者返回記錄的部分字段,如:

string GetNameByID(int nID) //根據員工ID返回員工姓名,這裏只需要

// 讀取姓名字段;

(提示:這種情況一般可以通過執行特定的查詢或存儲過程直接解決)

 

(4)    出於某些方面的考慮(例如:n-Tier系統中嚴格區分各Layer間的職責),無法(或者禁止)通過數據庫本身進行查詢過濾,這時就只有使用DataReader在讀取時進行過濾操作!

(提示:雖然DataView也能達到這種目的,但它的過濾前提是必須讀取到所有返回數據,所以性能上不如DataReader!)

 

 

作者簡介:

本文作者張雪峯 畢博全球開發中心 的高級開發工程師。他目前在中國上海 畢博全球開發中心 Core/EAI 部門工作,從事 .NET 技術的研究以及相關項目的開發。可以通過 [email protected] 與他聯繫。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章