淺談Asp.net 多層架構中的變量引用與傳遞

最近比較清閒,正好利用這個時間仔細研究了一下Asp.net的多層架構,主要參考的是 Wrox 的一本<.Net WebSite Programming Problem-Design-Solution>,個人覺得這本書寫的不錯。面向有一定.net基礎的開發人員,剛開始看起來可能覺得很難懂,但是仔細研究一下會發現,這本書是一本面向工程應用的優秀參考手冊。
  Asp.net的多層架構主要是爲了解決數據層,邏輯層,表示層等之間的關係。我的做法是這樣的:首先建立一個DataCore的基類。基類裏面封裝了一些低層的數據庫的基本操作,比如說數據庫聯接,調用存儲過程等等。在這裏面有一個地方值得注意,通過對一個函數的重載可以實現調用不同功能的存儲過程。以下代碼示例:
  
  protected int RunProcedure(string storedProcName, IDataParameter[] parameters, out int rowsAffected )
  {
  int result;
  
  Connection.Open();
  SqlCommand command = BuildIntCommand( storedProcName, parameters );
  rowsAffected = command.ExecuteNonQuery();
  result = (int)command.Parameters["ReturnValue"].Value;
  Connection.Close();
  return result;
  }
  
  protected SqlDataReader RunProcedure(string storedProcName, IDataParameter[] parameters )
  {
  SqlDataReader returnReader;
  
  Connection.Open();
  SqlCommand command = BuildQueryCommand( storedProcName, parameters );
  command.CommandType = CommandType.StoredProcedure;
  
  returnReader = command.ExecuteReader();
  //Connection.Close();
  return returnReader;
  }
  
  protected DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName )
  {
  DataSet dataSet = new DataSet();
  Connection.Open();
  SqlDataAdapter sqlDA = new SqlDataAdapter();
  sqlDA.SelectCommand = BuildQueryCommand( storedProcName, parameters );
  sqlDA.Fill( dataSet, tableName );
  Connection.Close();
  
  return dataSet;
  }
  
  protected void RunProcedure(string storedProcName, IDataParameter[] parameters, DataSet dataSet, string tableName )
  {
  Connection.Open();
  SqlDataAdapter sqlDA = new SqlDataAdapter();
  sqlDA.SelectCommand = BuildIntCommand( storedProcName, parameters );
  sqlDA.Fill( dataSet, tableName );
  Connection.Close();
  }
  
  道理很簡單,一看就懂。對於以後的操作有好處的。
  
  其次是要建立邏輯層,這個邏輯層基本上就是實例化數據層DataCore之後爲表示層返回一些DataSet,DataReader之類或是執行一些insert,update,delete之類語句。這個邏輯層也是爲了區分整個Project下面不同功能模塊。比如說用戶模塊起名叫做UserModel.cs,新聞模塊叫做NewsModel.cs之類。邏輯層的另一個好處就是可以爲表示層建立可以多次實例化的同一個對象或是方法。比如說User類,通過ID或是Username 查詢並建立的對象可以被表示層多次調用。
  
  最後是表示層,表示層的功能就是完成頁面邏輯。主要是接受客戶端數據然後經過簡單整合和判斷,傳遞給邏輯層處理。同樣,接收邏輯層傳遞來的Dataset或DataReader,表示在前臺頁面。
  
  數據在各個層次之間的關係相對獨立,但是又相對連續。
  
  獨立性:
  
  對於表示層之外的幾個層,都可以把單個的對象或是方法直接拿出來放到其他工程中。因爲每個曾都是爲了實現模型中獨立的功能而完成的。因爲在類似工程中的應用基本上不用太大改動,特別是一些相對更加原始的層,在這個示例中的DataCore就是一個典型的例子。
  
  連續性:
  
  數據在傳遞過程中有較強的連續性。舉一個例子,在表示層中有這樣一個根據Session中Userid返回一個Dataset,原本我是這樣寫的:
  
  表示層:
  
  DataSet UserInforRow = ObjectUser.GetUserInfor(Int32.Parse(Session["UserId"].ToString()));
  
  邏輯層:
  
  public DataSet GetUserInfor(int UserID)
  {
  SqlParameter[] parameters ={new SqlParameter("@UserID",SqlDbType.Int,4)};
  
  parameters[0].Value = UserID;
  
  using(DataSet UserInfor = RunProcedure("GetUserInfor",parameters,"UserInfor"))
  {
  return UserInfor;
  }
  }
  
  
  
  這樣可以編譯通過,但是在執行的時候提示錯誤,類型不匹配,語法上面沒有錯誤。但是錯誤出在,表示層傳進來的是一個Int32,在Sqlparameter中確是一個Int,4,本來以爲這樣的變量類型都是在每一個層次中相對獨立的,但是當他們之間傳遞數據的時候,出現了問題。
  
  對於這個問題的解決方案有兩種,無非是更改表示層還是更改邏輯層。更改邏輯層,就要改成
  
  SqlParameter[] parameters ={new SqlParameter("@UserID",SqlDbType.Int,32)};
  
  更改表示層要改爲:
  
  DataSet UserInforRow = ObjectUser.GetUserInfor(int.Parse(Session["UserId"].ToString()));
  
  兩個方案中顯然是更改表示層比較合理,因爲不能夠因爲一個變量的傳遞更改變邏輯層中的可以被其他表示層頁面所調用的方法。
  
  其他類似的變量傳遞和引用也遇到類似問題,雖然幾個層次相對獨立,但是在數據的傳遞上也相對連續。
  
  .net在web上面的應用可以做的很複雜,邏輯也很強,簡單的單頁面調用不是.net的特點也不能作爲工程應用。我也是接觸了一點,冰山一角,希望能起到一個拋磚引玉的作用. 
發佈了7 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章