漫談.Net PetShop和Duwamish ADO.NET數據庫編程(3)
2024-07-10 13:04:28
供稿:網友
 
.net petshop數據訪問剖析 
   
    ok,duwamish看完了,下面我們來看看petshop的數據訪問機制。 
   
    petshop只有一個項目,它采用的分層辦法是將中間層和數據層都寫成cs文件放在components目錄里,其中數據層就是一個名為database的類,它封裝了所有對數據庫的底層操作。下面是示例代碼段: 
   
   
  public void runproc(string procname, out sqldatareader datareader) { 
  sqlcommand cmd = createcommand(procname, null); 
  datareader = cmd.executereader(system.data.commandbehavior.closeconnection); 
  } 
   
    我們看到了一個跟duwamish截然不同的另一種數據訪問方式,它將所有的數據訪問方法抽象出來做成一個runproc方法,至于返回數據呢,呵呵,它有點偷懶,直接返回一個datareader給你,你自己去讀吧。還記得duwamish采用的層間數據傳輸載體是什么嗎?對了,是dataset,它被數據層填充后返回給了中間層。但是這里,數據層和傳輸層的數據傳輸載體變成了datareader,實際上,還不能稱它為數據載體,因為數據還沒開始讀呢,在這里,datareader的作用和指針有點類似,也許我們應該稱它為“數據引用”:) 
   
    接著往下看,datareader被怎么“處理”的: 
   
   
  public productresults[] getlist(string catid, int currentpage, int pagesize, ref int numresults) 
  { 
  numresults = 0; 
  int index=0; 
  sqldatareader reader = getlist(catid); 
  productresults[] results = new productresults[pagesize]; 
   
  // now loop through the list and pull out items of the specified page 
  int start = (int)((currentpage - 1) * pagesize); 
  if (start <= 0) start = 1; 
   
  // skip 
  for (int i = 0; i < start - 1; i++) { 
  if (reader.read()) numresults++; 
  } 
  if (start > 1) reader.read(); 
   
  // read the data we are interested in 
  while (reader.read()) { 
  if (index < pagesize) { 
  results[index] = new productresults(); 
  results[index].productid = reader.getstring(0); 
  results[index].name = reader.getstring(1); 
  index++; 
  } 
  numresults++; 
  } 
   
  reader.close(); 
   
  // see if need to redim array 
  if (index == pagesize) 
  return results; 
  else { 
  // not a full page, redim array 
  productresults[] results2 = new productresults[index]; 
  array.copy(results, results2, index); 
  return results2; 
  } 
  } 
   
    注意到currentpage和pagesize了嗎?原來在這里就進行了數據分頁,只返回滿足需要的最少的數據量,而不是象我們很多喜歡偷懶的人一樣,簡單的將整個datatable一股腦的綁定到datagrid,造成大量的數據冗余。 
   
    在這里,數據被真正的讀出來,并且被手動填充到一個自定義的對象數組中,我們來看看這個數組的定義: 
   
   
  public class productresults 
  { 
  private string m_productid; 
  private string m_name; 
   
  // product props 
  public string productid { 
  get { return m_productid; } 
  set { m_productid = value; } 
  } 
   
  public string name { 
  get { return m_name; } 
  set { m_name = value; } 
  } 
  } 
   
    非常之簡單,不過我有點奇怪為什么不使用struct呢?是不是.net中struct和class的性能差距已經可以忽略不計了? 
   
    分析總結 
   
    通過觀察這兩個商店的具體實現,我們得到了兩個不同的數據訪問模式,duwamish采用的是以dataset為核心,因為dataset提供了這方面大量的相關方法,所以整個應用的數據傳輸,數據格式定義,數據校驗都圍繞著dataset來進行,整個架構定義非常清晰和嚴謹,但是卻顯得有些龐大。petshop在整個程序中沒有采用一個dataset,程序非常的簡潔,輕靈,但是沒有duwamish那么強的健壯性。這兩個程序是microsoft公司不同的小組寫出來的代碼,所以有著不同風格。不過都應該能代表.net的標準模式。看到這里,你應該對文章開頭提出的那些疑問有一個比較形象的認識了吧。 
   
    另外,請再次注意,petshop在打開數據連接之后,并沒有馬上讀取數據,而是將datareader傳遞給另外的對象來執行數據讀的操作,然后才關閉連接。這樣,數據連接的時間加長了,而數據庫連接是一項非常寶貴的服務器資源,相比之下,dawamish在連接數據庫之后馬上進行填充,然后迅速釋放掉數據庫連接的方式更加有利于大量用戶的并發訪問。 
   
    再一點,上文的程序中沒有提到更新操作,petshop采用的是使用command對象執行單個存儲過程的方式來進行更新操作,是屬于一種在線即時數據更新模式。而dawamish采用的是dataadapter的update方法,將dataset的改變一次性的提交到數據庫中,屬于離線數據更新模式。這種模式的好處是可以一次性更新大批量數據,減少數據庫的連接次數。缺點是如果數據庫在改動非常頻繁的情況下需要實時的跟蹤數據變化就不合適了。需要根據具體的情況采用具體的數據更新辦法。 
   
    總的來說,如果您只需要快速的讀取數據并顯示出來,推薦您采用datareader,如果您需要對數據進行大量的修改,還有大量并發訪問的可能,而且不需要實時的跟蹤數據庫的變化,推薦您使用dataset。當然,這兩種情況有點極端了,實際的應用環境也許有著很復雜的條件,具體需要您自己審時度勢,綜合采用,不過我個人還是比較喜歡petshop那種輕靈的風格 :) 
   
    本文只嘗試對以上兩個典型的.net應用例程的數據訪問機制做了一個簡單的追蹤分析。 
國內最大的酷站演示中心!