[ASP.net Web Form] 不用撰寫後置程式碼的多欄位查詢撈資料
最近在日本MSDN看到有人討論
所以這邊紀錄一下吧
這樣寫的好處是在 Page_Load事件、查詢按鈕Click事件、GridView分頁事件,不用再各別處理撈資料,省得打字
但代價就是 Or 條件串太多,可能導致查詢效能不彰
至於撰寫技巧就如同之前提過的文章:[C#/Java] 不用動態組SQL字串的查詢程式碼
And ( ( 欄位變數 = 欄位變數預設值 ) Or ( Table欄位 = 欄位變數) )
所以請注意以下SqlDataSource的Select語句
<%@ Page Debug="true" Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:SqlDataSource runat="server" ID="sds_Categories"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="
SELECT [CategoryID], [CategoryName], [Description] FROM [Categories] Where ((@CategoryID = -1) Or (CategoryID = @CategoryID))
And ((@CategoryName ='') Or (CategoryName Like '%' + @CategoryName +'%'))" >
<SelectParameters>
<asp:ControlParameter ControlID="ddl_Categories" PropertyName="SelectedValue" Name="CategoryID" />
<asp:ControlParameter ControlID="txt_CategoryName" PropertyName="Text" Name="CategoryName" />
</SelectParameters>
</asp:SqlDataSource>
CategoryID:
<asp:DropDownList ID="ddl_Categories" runat="server">
<asp:ListItem Text="All" Value="-1" />
<asp:ListItem Text="1" Value="1" />
<asp:ListItem Text="2" Value="2" />
<asp:ListItem Text="3" Value="3" />
<asp:ListItem Text="4" Value="4" />
<asp:ListItem Text="5" Value="5" />
<asp:ListItem Text="6" Value="6" />
<asp:ListItem Text="7" Value="7" />
<asp:ListItem Text="8" Value="8" />
</asp:DropDownList>
CategoryName:<asp:TextBox runat="server" ID="txt_CategoryName" Text="" /><br />
<asp:Button Text="查詢" ID="btn_Query" runat="server" />
</div>
<div>
<asp:GridView runat="server" ID="gv_table" DataSourceID="sds_Categories"
AutoGenerateColumns="False" DataKeyNames="CategoryID" >
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
SortExpression="CategoryName" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
但執行後會發現網頁原始碼
TextBox Server Control,如果Text=””在呈現出HTML時,是不會加上Value的Attribute
所以導致網頁第一次執行沒有撈全部的資料
看了一下日本那邊的討論,折衷的辦法就是給Text=”All”
然後再改寫SqlDataSource的SelectCommand
<%@ Page Debug="true" Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:SqlDataSource runat="server" ID="sds_Categories"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="
SELECT [CategoryID], [CategoryName], [Description] FROM [Categories] Where ((@CategoryID = -1) Or (CategoryID = @CategoryID))
And ((@CategoryName ='All') Or (CategoryName Like '%' + @CategoryName +'%'))" >
<SelectParameters>
<asp:ControlParameter ControlID="ddl_Categories" PropertyName="SelectedValue" Name="CategoryID" />
<asp:ControlParameter ControlID="txt_CategoryName" PropertyName="Text" Name="CategoryName" />
</SelectParameters>
</asp:SqlDataSource>
CategoryID:
<asp:DropDownList ID="ddl_Categories" runat="server">
<asp:ListItem Text="All" Value="-1" />
<asp:ListItem Text="1" Value="1" />
<asp:ListItem Text="2" Value="2" />
<asp:ListItem Text="3" Value="3" />
<asp:ListItem Text="4" Value="4" />
<asp:ListItem Text="5" Value="5" />
<asp:ListItem Text="6" Value="6" />
<asp:ListItem Text="7" Value="7" />
<asp:ListItem Text="8" Value="8" />
</asp:DropDownList>
CategoryName:<asp:TextBox runat="server" ID="txt_CategoryName" Text="All" /><br />
<asp:Button Text="查詢" ID="btn_Query" runat="server" />
</div>
<div>
<asp:GridView runat="server" ID="gv_table" DataSourceID="sds_Categories"
AutoGenerateColumns="False" DataKeyNames="CategoryID" >
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
SortExpression="CategoryName" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
如此一來就都不用寫後置程式碼做出多數欄位查詢的效果
第一次執行畫面:(撈全部資料)
選擇下拉選單:
再篩選CategoryName:
還原下拉選單All,做CategoryName的查詢:
因為中文版資料庫安裝時預設定序是不分大小寫的,所以All可以輸入all,再按查詢,就又是撈全部的資料
而且因為是傳參數查詢,所以可防SQL Injection,(下圖撈不到資料)
2011.7.20
<asp:ControlParameter ControlID="ddl_Categories" PropertyName="SelectedValue" Name="CategoryID" />
<asp:ControlParameter ControlID="txt_CategoryName" PropertyName="Text" Name="CategoryName" ConvertEmptyStringToNull="false" />
</SelectParameters>
ConvertEmptyStringToNull="false"
這樣就可以
SELECT [CategoryID], [CategoryName], [Description] FROM [Categories] Where ((@CategoryID = -1) Or (CategoryID = @CategoryID))
And ((@CategoryName ='') Or (CategoryName Like '%' + @CategoryName +'%'))
如此一來,在TextBox中為空字串時,就可以撈全部資料了