導言
正如我們在上一節的教程中所看到的,有很多可供選擇的方式把參數的值傳遞到OjbectDataSource的方法裡。假如參數值是採用寫入程式碼方式,來源於頁面上的一個Web控制項,又或者其他可被資料來源Parameter對象讀取的源,那麼這個值可以綁定到輸入參數而不需要寫一行的代碼。
然而有些時候,參數值來自某些在資料來源的內建Parameter對象裡還沒有計算出來的源。假如我們的網站支援我們的考慮那麼我們也許希望參數基於當前登入使用者。又或者我們在參數傳送到ObjectDataSource的隱含對象的方法前做一些客戶化定製。
無論什麼時候調用ObjectDataSource的Seelect方法,它都會首先觸發它的Selecting事件,然後才調用ObjectDataSource的隱含對象的方法,完成後則激發ObjectDataSource ObjectDataSource的Selected 事件(圖一說明這些事件的順序)。可以在Selecting事件的事件委託中對參數的值進行設定或更改。
圖 1: ObjectDataSource的Selected 和 Selecting 事件分別在調用它的隱含對象的方法之前和之後觸發
這一節裡我們將看看添加一個接受一個輸入參數方法到DAL和BLL層,參數名為Month,int類型,方法返回一個EmployeesDataTable對象,裡邊包含的是僱傭周年紀念都指定月份的僱員。我們的例子將編碼設定為基於當前月份,顯示一個“本月僱用周年紀念員工”列表。
讓我們開始吧!
第一步: 添加一個方法到 EmployeesTableAdapter
在我們的第一個例子裡,我們需要添加一個方法來擷取那些僱用日期(HireDate)在某個指定月份的員工。在我們的程式架構下為了提供這個功能,我們首先需要在通過特定SQL語句映射出來的EmployeesTableAdapter中建立一個方法。為了實現這一點,首先開啟Northwind類型化資料集,在EmployeesTableAdapter標籤上右鍵選擇“添加查詢”。
圖 2: 在 EmployeesTableAdapter裡添加一個查詢
選擇返回一個或多個行和列的SQL語句。當到達指定SELECT語句視窗時,EmployeesTableAdapter已經裝載了預設的SELECT語句。簡單地,添加一個WHERE子句:WHERE DATEPART(m, HireDate) = @Month 。其中DATEPART是T-SQL裡的一個函數,用作返回日期類型的一部分;在這裡,我們使用DATEPART函數返回僱用日期(HireDate)列的月份部分。
圖 3: 僅返回 HireDate 列的值小於等於參數 @HiredBeforeDate的行
最後,分別把預設的方法名FillBy和GetDataBy更改為FillByHiredDateMonth和GetEmployeesByHiredDateMonth 。
圖 4: 選擇比FillBy和GetDataBy更恰當的方法名稱
點擊“完成”結束嚮導並返回到資料集的設計介面。這時候EmployeesTableAdapter會包含一套新的方法來擷取指定月份僱用的員工。
圖 5: 新的方法出現在資料集的設計介面
第二步: 在商務邏輯層添加方法 GetEmployeesByHiredDateMonth(month)
因為我們的程式架構使用了單獨的一層來處理商務邏輯和資料邏輯,我們需要在BLL裡增加一個方法,該方法調用DAL的方法擷取指定月份裡僱用的員工。開啟檔案EmployeesBLL.cs並添加下面這個方法:
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]public Northwind.EmployeesDataTable GetEmployeesByHiredDateMonth(int month){ return Adapter.GetEmployeesByHiredDateMonth(month);}
和此類裡的其他方法一樣,GetEmployeesByHiredDateMonth(month)僅僅是簡單地調用DAL並返回結果。
第三步: 顯示僱用周年紀念日在本月份的員工
最後一部我們舉例說明如何顯示僱用周年紀念在本月份的員工。首先,添加一個GridView控制項到頁面ProgrammaticParams.aspx,該頁面在檔案夾BasicReporting裡。添加一個新的ObjectDataSource控制項作為它的資料來源。配置ObjectDataSource使用類EmployeesBLL並指定SelectMethod屬性為GetEmployeesByHiredDateMonth(month)。
圖 6: 使用EmployeesBLL 類
圖 7: 選擇GetEmployeesByHiredDateMonth(month)方法
最後一屏要求我們給month參數提供參數源。既然我們將編碼設定這個值,就讓參數源維持它的預設選項None,點擊“完成”。
圖 8: 讓參數源設定為None
這將在ObjectDataSource的SelectParameters集合裡建立一個未指定參數值的Parameter對象。
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetEmployeesByHiredDateMonth" TypeName="EmployeesBLL"> <SelectParameters> <asp:Parameter Name="month" Type="Int32" /> </SelectParameters></asp:ObjectDataSource>
要編碼設定這個參數值,我們需要給ObjectDataSource的Selecting事件添加一個事件委託。為了實現這一點,到設計檢視裡在ObjectDataSource上雙擊。另一種方式是選中ObjectDataSource在屬性視窗裡點擊黃色閃電小表徵圖,然後,直接在Selecting這一欄裡雙擊或者輸入一個你要使用的事件委託的名稱。
圖 9:點擊屬性視窗裡的閃電表徵圖列出Web控制項的所有事件
兩種途徑都可以在頁面的程式碼後置類別裡增加一個對ObjectDataSource的Selecting事件的事件委託。在這個事件委託裡,我們可以通過使用e.InputParameters[parameterName]讀取參數的值,其中parameterName的值是<asp:Parameter>標籤裡的屬性Name的值(InputParameters也可以按照索引訪問,用e.InputParameters[index])。為了把month參數設定為當前月份,需要在Selecting事件委託裡加入如下代碼:
protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e){ e.InputParameters["month"] = DateTime.Now.Month;}
當通過瀏覽器訪問該頁面,我們可以看到只有一個員工是在當前月份(三月)僱用的:Laura Callahan,他從1994年3月開始僱用。
圖 10: 僱用周年紀念日在本月份的員工被顯示出來了
總結
雖然可以用特定的方式聲明ObjectDataSource的參數值而不需要寫代碼,編程設定參數值同樣很容易。我們需要做的僅僅是給ObjectDataSource的Selecting事件增加一個事件委託,它在調用隱含對象的方式前觸發,並且通過InputParameters集合手工設定一個或多個參數值。
本節結束基本這一章。下一節我們開始主從資料一章,這一章裡我們將著眼於允許訪問者篩選資料和主從資料處理的技巧。
祝編程快樂!
作者簡介
Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用微軟Web技術。Scott是個獨立的技 術諮詢顧問,培訓師,作家,最近完成了將由Sams出版社出版的新作,24小時內精通ASP.NET 2.0。他的聯絡電郵為mitchell@4guysfromrolla.com,也可以通過他的部落格http://ScottOnWriting.NET與他聯絡。