使用下拉列表选择项来搜索gridview?

时间:2011-05-18 15:55:04

标签: c# asp.net sql-server visual-studio

我有一个从四个表填充的gridview,而select命令(如下所示)功能齐全。我希望能够搜索gridview,并且只显示那些“Status”列值等于下拉列表中所选项目的行。我相信我有正确的选择声明(也在下面列出),但我只希望gridview在按钮点击时显示搜索结果。如何使这个select语句有条件?换句话说,我如何才能使用Search select语句仅在用户点击搜索按钮时使用?

常规选择声明:

SelectCommand="SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status FROM Submission INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId"

我的搜索选择语句:

`SelectCommand="SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, 

Broker.EntityType, Submission.Coverage, Status.Status FROM Submission WHERE Status = '" + Ddl.SelectedItem.Text + "' INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId 

INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId">`

完整的gridview / droplist代码:

    <asp:DropDownList ID="DropDownList1" runat="server" 
            DataSourceID="SqlDataSource2" DataTextField="Status" DataValueField="Status">

        </asp:DropDownList>
        <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
            ConnectionString="<%$ ConnectionStrings:MyConnectionString %>" 
            SelectCommand="SELECT [Status] FROM [Status]"></asp:SqlDataSource>
        &nbsp;<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        &nbsp;
        <asp:Button ID="Button1" runat="server" Text="Search" />
</asp:Panel>
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" 
        EmptyDataText="There are no data records to display." AllowPaging="True" 
        BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px" 
        CellPadding="3" GridLines="Vertical" HorizontalAlign="Center" 
        AllowSorting="True" >
        <AlternatingRowStyle BackColor="#DCDCDC" />

        <Columns>

            <asp:BoundField DataField="SubId" HeaderText="Submission Id" 
                SortExpression="SubId" >
            </asp:BoundField>
            <asp:BoundField DataField="CustName" HeaderText="Customer" 
                SortExpression="CustName" />
            <asp:BoundField DataField="CustCity" HeaderText="Customer City" 
                SortExpression="CustCity" />
            <asp:BoundField DataField="CustState" HeaderText="Customer State" 
                SortExpression="CustState" />
            <asp:BoundField DataField="BroName" HeaderText="Broker" 
                SortExpression="BroName" />
            <asp:BoundField DataField="BroState" HeaderText="Broker State" 
                SortExpression="BroState" />
            <asp:BoundField DataField="EntityType" HeaderText="Entity Type" 
                SortExpression="EntityType" />
            <asp:BoundField DataField="Coverage" 
                HeaderText="Coverage" SortExpression="Coverage" />
            <asp:BoundField DataField="Status" HeaderText="Status" 
                SortExpression="Status" />

            <asp:HyperLinkField DataNavigateUrlFields="SubId" 
                DataNavigateUrlFormatString="View.aspx?SubId={0}" Text="View" />
            <asp:HyperLinkField DataNavigateUrlFields="SubId" 
                DataNavigateUrlFormatString="ViewEdit.aspx?SubId={0}" HeaderText="Edit" 
                Text="Edit" />

        </Columns>
        <FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
        <HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
        <RowStyle BackColor="#EEEEEE" ForeColor="Black" />
        <SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
        <SortedAscendingCellStyle BackColor="#F1F1F1" />
        <SortedAscendingHeaderStyle BackColor="#0000A9" />
        <SortedDescendingCellStyle BackColor="#CAC9C9" />
        <SortedDescendingHeaderStyle BackColor="#000065" />
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:MyConnectionString %>" 
        ProviderName="<%$ ConnectionStrings:ProductInstanceString.ProviderName %>" 



        SelectCommand="SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status FROM Submission INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId">

    </asp:SqlDataSource>

2 个答案:

答案 0 :(得分:1)

首先,您肯定希望在SQL中使用参数。您发布的示例很容易受到SQL注入攻击。

其次,您可以通过使用存储过程(也具有许多其他好处)来实现一种类型的查询或另一种查询。在该过程中,您可以检查要传入的状态参数是否为空。如果它为null,则使用常规,如果它不使用搜索语句。

在你的数据库中,你可以创建一个看起来像这样的存储过程(它可能更优雅,但这是一个简单的例子):

CREATE PROCEDURE [dbo].[GetStuffByStatus]

@status varchar(255) = null

AS 
BEGIN

IF @status IS NOT NULL
BEGIN

    SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, 

    Broker.EntityType, Submission.Coverage, Status.Status 

    FROM Submission 

    WHERE Status = @status

    INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId 

    INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId

END
ELSE
    SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status 

    FROM Submission 

    INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId 
    INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId

END

然后你可以适当地编辑你的SqlDataSource:

<asp:SqlDataSource ID="SqlDataSource2" runat="server" 
        ConnectionString="<%$ ConnectionStrings:MyConnectionString %>" 
        SelectCommand="GetStuffByStatus" SelectCommandType="StoredProcedure">
        <SelectParameters>
            <asp:ControlParameter Name="status" ControlID="DtopDownList1" PropertyName="SelectedValue" ConvertEmptyStringToNull="true" />
        </SelectParameters>
</asp:SqlDataSource>

然后,如果您不想按状态过滤,请确保使用此参数传递任何内容(DropDownList SelectedValue为空)。向DropDownList添加一个默认的空值:

<asp:DropDownList ID="DtopDownList1" runat="server" DataSourceID="SqlDataSource1" DataTextField="someidentifier" DataValueField="someidentifier" AppendDataBoundItems="true">
    <asp:ListItem Text="No filter" Value="" />
</asp:DropDownList>

首先让SqlDataSource处理非过滤(空)的情况我遇到了一些麻烦,我不得不为GridView的SqlDataSource添加一个OnSelecting处理程序。我将此属性添加到SqlDataSource:

OnSelecting="SqlDataSource2_Selecting"

并编写了一个检查空案例的处理程序,并将参数设置为DBNull:

protected void SqlDataSource2_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
    if (DtopDownList1.SelectedValue == String.Empty)
    {
        ((SqlCommand)e.Command).Parameters["@status"].Value = DBNull.Value;
    }
}

我已经测试了这个解决方案,它可以按照您的描述运行。

当然,执行此操作的最佳做​​法是编写自己的数据层,以更恰当地处理此逻辑,但这可能超出了此问题的范围。

答案 1 :(得分:1)

为了展示对我有用的东西,这是我的代码。它运作正常。关于@ashelvey的答案,虽然我没有测试他的方法,但他对参数化是正确的。我没有的唯一原因是我正在进行一个培训项目,我的处理程序特别告诉我现在要避免它。该站点不用于部署。无论如何,我原来的问题是“如何在按钮点击时更改选择命令?”这是答案:

protected void BtnStatusSearch_Click(object sender, EventArgs e)
{
    SqlDataSource1.SelectCommand = "SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status FROM Submission INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId WHERE Status.Status = '" + DdlStatus.SelectedItem.Text + "'";
    SqlDataSource1.DataBind();
}