這篇文章将建立一列包含checkbox控件的datagrid,這個控件允許使用者對明細浏覽進行多列選擇。如果沒有恢複對于動态sql獲得該功能的一種方法,那麼必須使用in操作。
在文章的結尾,我們寫了一個sqlserver使用者自定義函數(udf),為了将一個字元串分解成帶分隔符的子字元串。在這篇文章中,我們能看到這樣一個udf如何派得上用場。我們将建立一個web表單,在此使用者可以通過選擇checkbox控件而選擇一些在datagrid中的記錄。對這些被檢查的記錄的明細将會出現在表單中的另一個datagrid中。這個表單像來如圖所示。
在下面顯示了我們用來建立表單的aspx。注意:如何使用templatecolumn和checkbox控件增加datagrid列。我們也使用datagrid的datakeyfield屬性來告訴對象,在資料庫記錄的哪一個字段将會包含第一行的關鍵字标示符。
<formid="form1"method="post"runat="server">
<asp:datagridid="datagrid1"runat="server"
autogeneratecolumns="false"datakeyfield="employeeid">
<columns>
<asp:templatecolumn>
<itemtemplate>
<asp:checkboxrunat="server"id="employeecheckbox"/>
</itemtemplate>
</asp:templatecolumn>
<asp:templatecolumn>
<itemtemplate>
<%#databinder.eval(container.dataitem,"lastname")%>,
<%#databinder.eval(container.dataitem,"firstname")%>
</itemtemplate>
</asp:templatecolumn>
</columns>
</asp:datagrid>
<hr>
<asp:buttonid="orders"runat="server"text="vieworders"></asp:button>
<asp:datagridid="datagrid2"runat="server"autogeneratecolumns="true"/>
</form>
當表單加載初始化時,需要組裝頂端的datagrid。代碼使用enterpriselibrary來存取sqlsevernorthwind例子資料庫并且執行“selectemployeeid,firstname,lastnamefromemployees”這一語句。加載事件的代碼如下:
privatevoidpage_load(objectsender,system.eventargse)
{
if(!page.ispostback)
{
databasedb=databasefactory.createdatabase();
dbcommandwrapperdbcommandwrapper;
using(dbcommandwrapper=db.getsqlstringcommandwrapper(select_employees))
using(idatareaderdatareader=db.executereader(dbcommandwrapper))
datagrid1.datasource=datareader;
datagrid1.databind();
}
}
當使用者單擊“orders”按鈕時,我們想顯示與資料庫中的那些與employees相配并與orders資料相關的第二個資料表格。這樣做的一種方法是建立動态的sql并且使用所有employeeids所需的where語句的or條件。
第二個方法是使用where語句的in操作。in操作将會一清單達式進行比較。例如,下列語句傳回employee中ids7和4之間的資訊。
selectemployeeid,firstname,lastnamefromemployeeswhereemployeeidin(7,4)
在觀念上說,我願意使用一個單一字元串參數來查詢所傳遞的ids,然而,也許作為一個單字元串,不能對in操作使用一個單一字元串參數。如果那樣,sql語句會這樣“whereemployeein(‘7,4’)”,并且資料庫因為employeeid屬于類型int—不屬于varchar類型而傳回一個錯誤消息。
不過,我們使用文章中構造的split函數将字元串分離成不同的值。向split函數傳遞字元串‘7,4’,并且我們會得到與值4和7相對應的兩條記錄。選擇employees并且計算它們的定單總數的sql查詢,将會如下:
selectcount(*)asorders,e.firstname,e.lastname
fromorderso
innerjoinemployeeseono.employeeid=e.employeeid
wheree.employeeidin(selectvaluefromfn_split(@employeeids,','))
groupbyfirstname,lastname
orderbycount(*)desc
使用以上查詢所需要的是必須建立和傳遞@employeeids參數。這個參數将是用逗号隔開的ids清單。為了建立該字元串,為了弄明白行是否被使用者選擇,我們需要使用一個循環,這一循環以行數循環次數,并且檢查每一個checkbox控件。如果使用者選擇了行,通過從表的datakeys屬性中(它被建立在aspx檔案中來指向employeeid字段)提取檢驗人,将關鍵字儲存在employee中。
privatestringgetcheckedemployeeids()
stringdelimiter=string.empty;
stringbuilderemployeeids=newstringbuilder();
for(inti=0;i<datagrid1.items.count;i++)
checkboxcheckbox;
checkbox=datagrid1.items[i].findcontrol("employeecheckbox")ascheckbox;
if(checkbox!=null&&checkbox.checked==true)
employeeids.append(delimiter+datagrid1.datakeys[i].tostring());
delimiter=",";
returnemployeeids.tostring();
以上方法傳回一個字元串,像“10,7,20”。對orders按鈕單擊事件處理器将涉及這樣一個方法,将資訊傳遞至sql以得到employees和orders的清單,并且将其結果綁定在第二個datagrid對象中。
privatevoidorders_click(objectsender,system.eventargse)
stringemployeeids=getcheckedemployeeids();
databasedb=databasefactory.createdatabase();
dbcommandwrapperdbcommandwrapper;
using(dbcommandwrapper=db.getsqlstringcommandwrapper(select_orders))
dbcommandwrapper.addinparameter("@employeeids",dbtype.string,employeeids);
using(idatareaderdatareader=db.executereader(dbcommandwrapper))
datagrid2.datasource=datareader;
datagrid2.databind();