使用 SqlDataSource 进行搜索

Posted

技术标签:

【中文标题】使用 SqlDataSource 进行搜索【英文标题】:Using SqlDataSource for searching 【发布时间】:2015-11-08 00:39:48 【问题描述】:

我正在尝试使用 sqldatasource 使用文本框在 GridView 中进行搜索,并启用了 editupdatepaging;但是,当我单击 update 成功搜索后,过滤后的 GridView 并没有显示,而是显示了每个数据的整个 GridView。谢谢,请指教。

aspx.cs 页面:

 namespace Inventory

    public partial class Results : System.Web.UI.Page
    
        //SqlConnection conn = new SqlConnection("Data Source=10.10.101.188;Initial Catalog=ActioNetITInventory;User ID=rails.sa;Password=ActioNet1234");
        private String ConnString = ConfigurationManager.ConnectionStrings["ActioNetITInventoryConnectionString"].ConnectionString;


        protected void Page_Load(object sender, EventArgs e)
        


            if (!IsPostBack)
            
                //BindData();
                //BindData2();
                //BindData3();



            //end if


        

        protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        

            BindData();
            GridView1.PageIndex = e.NewPageIndex;
            GridView1.DataBind();

        //end page load

        protected void BindData()
        
            using (SqlConnection sqlCon = new SqlConnection(ConnString))
            
                using (SqlCommand cmd = new SqlCommand())
                
                    cmd.CommandText = "SELECT * FROM [Inventory]";
                    cmd.Connection = sqlCon;
                    sqlCon.Open();
                    SqlDataAdapter da = new SqlDataAdapter(cmd);
                    DataTable dt = new DataTable();
                    da.Fill(dt);




                    GridView1.DataSourceID = null;
                    GridView1.DataSource = dt;
                    GridView1.DataBind();
                    sqlCon.Close();

                //end using
            //end using

        

        protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
        
            GridView1.EditIndex = e.NewEditIndex;
            BindData();
        

        protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
        
            var serial = GridView1.DataKeys[e.RowIndex].Value;
            GridViewRow row = GridView1.Rows[e.RowIndex] as GridViewRow;
            //getting row field details

            TextBox Assigned = row.FindControl("txtAssigned") as TextBox;
            TextBox Location = row.FindControl("txtLocation") as TextBox;
            TextBox Notes = row.FindControl("txtNotes") as TextBox;

            using (SqlConnection sqlCon = new SqlConnection(ConnString))
            
                string sql = "UPDATE Inventory SET Assigned=@Assigned, " + "Location=@Location, Notes=@Notes" + " WHERE Serial = @Serial";

                using (SqlCommand cmd = new SqlCommand(sql, sqlCon))
                

                    cmd.Parameters.AddWithValue("@Assigned", Assigned.Text.Trim());
                    cmd.Parameters.AddWithValue("@Location", Location.Text.Trim());
                    cmd.Parameters.AddWithValue("@Notes", Notes.Text);
                    cmd.Parameters.AddWithValue("@Serial", serial);

                    sqlCon.Open();
                    cmd.ExecuteNonQuery();
                    sqlCon.Close();



                //end using
            //end using


            status.Visible = true;
            status.Text = "" + Assigned.Text + "has been added successfully!";
            status.ForeColor = System.Drawing.Color.Green;


            GridView1.EditIndex = -1;
            BindData();
        

        protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        

            GridView1.EditIndex = -1;
            BindData();
        

html页面:

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False" DataKeyNames="Serial" DataSourceID="SqlDataSource1" CellPadding="4" ForeColor="#333333" GridLines="None" Width="1575px"
         OnPageIndexChanging="GridView1_PageIndexChanging" OnRowEditing="GridView1_RowEditing" OnRowUpdating="GridView1_RowUpdating" OnRowCancelingEdit="GridView1_RowCancelingEdit">
        <AlternatingRowStyle BackColor="White" ForeColor="#284775" />
    <Columns>
        <asp:CommandField ShowCancelButton="true" ShowEditButton="true" />
        <asp:TemplateField HeaderText="Type" SortExpression="Type">
                <ItemTemplate>
                    <asp:Label ID="lblType" runat="server" Text='<%#Eval("Type") %>'></asp:Label>
                </ItemTemplate>
                <FooterTemplate>
                    <asp:Button ID="btnInsert" runat="server" Text="Insert" CommandName="Add" />
                </FooterTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Make" SortExpression="Make">
                <ItemTemplate>
                    <asp:Label ID="lblMake" runat="server" Text='<%#Eval("Make") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>


            <asp:TemplateField HeaderText="Model" SortExpression="Model">
                <ItemTemplate>
                    <asp:Label ID="lblModel" runat="server" Text='<%#Eval("Model") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>


            <asp:TemplateField HeaderText="Serial" SortExpression="Serial">
                <ItemTemplate>
                    <asp:Label ID="lblSerial" runat="server" Text='<%#Eval("Serial") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Assigned" SortExpression="Assigned">
                <ItemTemplate>
                    <asp:Label ID="lblAssigned" runat="server" Text='<%#Eval("Assigned") %>'></asp:Label>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:TextBox ID="txtAssigned" runat="server" Text='<%#Bind("Assigned") %>'></asp:TextBox>
                </EditItemTemplate>
                <FooterTemplate>
                    <asp:TextBox ID="txtAssigned" runat="server"></asp:TextBox>
                </FooterTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Location" SortExpression="Location">
                <ItemTemplate>
                    <asp:Label ID="lblLocation" runat="server" Text='<%#Eval("Location") %>'></asp:Label>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:TextBox ID="txtLocation" runat="server" Text='<%#Bind("Location") %>'></asp:TextBox>
                </EditItemTemplate>
                <FooterTemplate>
                    <asp:TextBox ID="txtLocation" runat="server"></asp:TextBox>
                </FooterTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Notes" SortExpression="Notes">
                <ItemTemplate>
                    <asp:Label ID="lblNotes" runat="server" Text='<%#Eval("Notes") %>'></asp:Label>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:TextBox ID="txtNotes" runat="server" TextMode="MultiLine" Text='<%#Bind("Notes") %>'></asp:TextBox>
                </EditItemTemplate>
                <FooterTemplate>
                    <asp:TextBox ID="txtNotes" runat="server"></asp:TextBox>
                </FooterTemplate>
            </asp:TemplateField>
    </Columns>
        <EditRowStyle BackColor="#999999" />
        <FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
        <PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
        <RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
        <SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
        <SortedAscendingCellStyle BackColor="#E9E7E2" />
        <SortedAscendingHeaderStyle BackColor="#506C8C" />
        <SortedDescendingCellStyle BackColor="#FFFDF8" />
        <SortedDescendingHeaderStyle BackColor="#6F8DAE" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ActioNetITInventoryConnectionString %>" DeleteCommand="DELETE FROM [Inventory] WHERE [Serial] = @Serial" InsertCommand="INSERT INTO [Inventory] ([Type], [Make], [Model], [Serial], [Assigned], [Location], [Notes]) VALUES (@Type, @Make, @Model, @Serial, @Assigned, @Location, @Notes)" SelectCommand="SELECT * FROM [Inventory] WHERE ([Type] = @Type)" UpdateCommand="UPDATE [Inventory] SET [Type] = @Type, [Make] = @Make, [Model] = @Model, [Assigned] = @Assigned, [Location] = @Location, [Notes] = @Notes WHERE [Serial] = @Serial">
    <DeleteParameters>
        <asp:Parameter Name="Serial" Type="String" />
    </DeleteParameters>
    <InsertParameters>
        <asp:Parameter Name="Type" Type="String" />
        <asp:Parameter Name="Make" Type="String" />
        <asp:Parameter Name="Model" Type="String" />
        <asp:Parameter Name="Serial" Type="String" />
        <asp:Parameter Name="Assigned" Type="String" />
        <asp:Parameter Name="Location" Type="String" />
        <asp:Parameter Name="Notes" Type="String" />
    </InsertParameters>
    <SelectParameters>
        <asp:FormParameter FormField="typeTextBox" Name="Type" Type="String" />
    </SelectParameters>
    <UpdateParameters>
        <asp:Parameter Name="Type" Type="String" />
        <asp:Parameter Name="Make" Type="String" />
        <asp:Parameter Name="Model" Type="String" />
        <asp:Parameter Name="Assigned" Type="String" />
        <asp:Parameter Name="Location" Type="String" />
        <asp:Parameter Name="Notes" Type="String" />
        <asp:Parameter Name="Serial" Type="String" />
    </UpdateParameters>
</asp:SqlDataSource>

【问题讨论】:

【参考方案1】:

您正在将 GridView 控件的数据源与此行上的 SqlDataSource 控件分离:

GridView1.DataSourceID = null;

由于在BindData() 方法中您正在执行一个没有WHERE 子句的查询,它会返回所有要绑定到网格的行,如下几行所示:

protected void BindData()

    using (SqlConnection sqlCon = new SqlConnection(ConnString))
    
        using (SqlCommand cmd = new SqlCommand())
        
            cmd.CommandText = "SELECT * FROM [Inventory]";
            cmd.Connection = sqlCon;
            sqlCon.Open();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            da.Fill(dt);

            GridView1.DataSourceID = null;
            GridView1.DataSource = dt;
            GridView1.DataBind();
            sqlCon.Close();
        //end using
    //end using

这实际上破坏了您的搜索条件,因为没有条件(WHERE 子句)应用于 SQL 查询。

您需要让SqlDataSource 控件的SelectCommand 支持具有“搜索”值和不具有“搜索”值。这样做的一种方法是这样的:

SelectCommand="SELECT * FROM [Inventory] WHERE ([Type] = @Type OR [Type] = '')"

OR 逻辑添加到您的WHERE 子句将不会过滤掉任何行(假设您的Type 值都不是空白并且当您省略搜索时(即搜索文本框中的空白字符串)。


就我个人而言,我会创建一个返回 DataTable 对象并传入搜索条件的方法,该方法根据“搜索”字符串是否为空来构造两个单独的 SQL 语句,如下所示:

private DataTable GetData(string searchTerm)

    DataTable dt = null;

    // Check to see if search term is null or empty
    if(!string.IsNullOrEmpty(searchTerm)
    
        // Build SQL statement with WHERE clause
        using (SqlConnection sqlCon = new SqlConnection(ConnString))
        
            using (SqlCommand cmd = new SqlCommand())
            
                cmd.CommandText = "SELECT * FROM [Inventory] 
                                   WHERE [Type] = @searchTermParameter";
                cmd.Parameters.Add(new SqlParameter("@searchTermParameter", searchTerm));
                cmd.Connection = sqlCon;
                sqlCon.Open();
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                dt = new DataTable();
                da.Fill(dt);
            //end using
        //end using
    
    else
    
        // Build SQL statement without WHERE clause,
        // because we are not searching for anything
        using (SqlConnection sqlCon = new SqlConnection(ConnString))
        
            using (SqlCommand cmd = new SqlCommand())
            
                cmd.CommandText = "SELECT * FROM [Inventory]";
                cmd.Connection = sqlCon;
                sqlCon.Open();
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                dt = new DataTable();
                da.Fill(dt);
            //end using
        //end using
    

    return dt;

现在您可以让您的DataBind 方法只接受一个DataTable 对象,它的唯一职责是将数据绑定到GridView 控件,如下所示:

protected void BindData(DataTable dt)

    GridView1.DataSource = dt;
    GridView1.DataBind();

【讨论】:

谢谢!现在我试图在回发期间绑定数据,但是我在 BindData() 参数中放了什么?下面的代码:protected void Page_Load(object sender, EventArgs e) if(!IsPostBack) BindData(); @Terrence Sanchez - 只需调用 GetData (string.Empty);,这将获取所有行,因为 GetData 方法中的条件逻辑。 我这样做了,但是,当我单击第二个进入第二页时,什么都没有显示。这是代码:protected void GridView1_PageIndexChanging(object sender, GridViewPageEvenArgs e) GridView1.PageIndex = e.NewPageIndex; GetData(string.Empty); //end paging @Terrence Sanchez - 您需要在页面索引更改事件处理程序中调用 BindData (string.Empty); @Terrence Sanchez - 抱歉的意思是BindData (GetData (string.Empty ));

以上是关于使用 SqlDataSource 进行搜索的主要内容,如果未能解决你的问题,请参考以下文章

无记录时显示gridview表头,并增加一行显示“没有记录”绑定SqlDataSource控件时

绑定前修改sqldatasource选中的数据?

SqlDataSource.Select()?我该如何使用它? (ASP.net)

SqlDataSource 是不是始终保持数据库连接打开?

Telerik Reporting - 使用 SqlDataSource 时无法在 Chrome 中导出

vs2017关于SqlDataSource无法使用参数控件绑定的问题