其它<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
結束ADO.NET剖析前,不得不提提DataReader與DataSet間的兄弟
之爭。
就作者所看過的資料,幾乎所有的都建議實際情況具體分析,剩下
很少很少的則全憑個人習慣決定。
在學習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解決方案可以非常方便的支持序列化操作(如:Remoting,WebServices),同時,與XML的關係更是親密無比,這對於和其它系統的交互來說也是至關重要的。
分析過一些技術和方案,相信讀者朋友已有一些體會。值此收官之際,如果非要在這裏提供一個“綜上所述”,那作者的建議就非常明確:
在企業級應用開發中,儘可能的採用DataSet(DataTable / DataView)+ Cache Management解決方案!
其它開發中,只在如下4種情況才考慮使用DataReader(就作者經驗來說,大部分使用DataReader都屬第2種情況):
(1) 對資源要求比較苛刻的場合,這裏的資源主要指內存和數據庫連接;
(2) 希望在讀取數據庫返回結果集時作自定義處理,例如:在讀取一條記錄後立刻終止處理,或者在讀取時作計算操作。
(提示:這種情況類似於XML中的SAX(Simple API for XML)技術,無需一次性讀入所有XML數據即可進行操作;相反的,DOM(Document Object Model)則要求必須裝載所有XML數據後才能開始操作(MSXML4.0已開始允許只讀取XML文檔部分數據即可開始操作,這是後話)!)
(3) 只希望得到返回記錄數或者返回記錄的部分字段,如:
string GetNameByID(int nID) //根據員工ID返回員工姓名,這裏只需要
// 讀取姓名字段;
(提示:這種情況一般可以通過執行特定的查詢或存儲過程直接解決)
(4) 出於某些方面的考慮(例如:n-Tier系統中嚴格區分各Layer間的職責),無法(或者禁止)通過數據庫本身進行查詢過濾,這時就只有使用DataReader在讀取時進行過濾操作!
(提示:雖然DataView也能達到這種目的,但它的過濾前提是必須讀取到所有返回數據,所以性能上不如DataReader!)
作者簡介:
“本文作者張雪峯 是 畢博全球開發中心 的高級開發工程師。他目前在中國上海 畢博全球開發中心 Core/EAI 部門工作,從事 .NET 技術的研究以及相關項目的開發。可以通過 [email protected] 與他聯繫。”