嵌套的 Gridview 冗余值

Nested Gridview redundant values

我有 2 个网格视图。 Gridview1Gridview2。 两者都有共同领域 "ID" 当我 Select Gridview1 (ID=1) 中的第一行时,Gridview2ID=1 的值显示在嵌套区域中,但值显示在 Gridview1 的每一行中。当我删除 "select" 时,Gridview2 没有任何显示。 当我打开页面时,我希望显示 Gridview1,然后嵌套 Gridview2 显示来自 Gridivew1 的个人 ID 的内容。我不希望 select 看到所有内容,我只希望两个表都显示它们的数据。

我做了什么:

后面的代码:

public partial class _Webform : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            GridView gv2 = (GridView)e.Row.FindControl("GridView2");

            string connString = @"Data Source=SRV\\SQLEXPRESS;Initial Catalog=Test_Database;Integrated Security=True";
            string query = "select * from dbo.task where PO_ID =" + e.Row.Cells[0].Text;

            SqlConnection conn = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand(query, conn);
            conn.Open();

            SqlDataAdapter da = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();
            da.Fill(dt);
            conn.Close();
            da.Dispose();

            gv2.DataSource = dt;
            gv2.DataBind();
        }
    }
}

HTML 标记:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="PO_ID" DataSourceID="SqlDataSource1" EnableModelValidation="True">
    <Columns>
        <asp:CommandField ShowSelectButton="True" />
        <asp:BoundField DataField="PO_ID" HeaderText="PO_ID" SortExpression="PO_ID" />
        <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" />
        <asp:BoundField DataField="UserDate" HeaderText="UserDate" SortExpression="UserDate" />
        <asp:BoundField DataField="PO_Note" HeaderText="PO_Note" SortExpression="PO_Note" />
        <asp:BoundField DataField="Invoice_No" HeaderText="Invoice_No" SortExpression="Invoice_No" />
        <asp:TemplateField HeaderText="Tasks">
            <ItemTemplate>
                <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource2" EnableModelValidation="True">
                    <Columns>
                        <asp:BoundField DataField="PO_ID" HeaderText="PO_ID" SortExpression="PO_ID" />
                        <asp:BoundField DataField="Username" HeaderText="Username" SortExpression="Username" />
                        <asp:BoundField DataField="UserDate" HeaderText="UserDate" SortExpression="UserDate" />
                        <asp:BoundField DataField="Cost" HeaderText="Cost" SortExpression="Cost" />
                        <asp:BoundField DataField="column1" HeaderText="column1" SortExpression="column1" />
                        <asp:BoundField DataField="Invoice_Date" HeaderText="Invoice_Date" SortExpression="Invoice_Date" />
                        <asp:BoundField DataField="Invoice_No" HeaderText="Invoice_No" SortExpression="Invoice_No" />
                    </Columns>
                </asp:GridView>
                <asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:Test_DatabaseConnectionString3 %>" SelectCommand="SELECT [PO_ID], [Username], [UserDate], [Cost], [_Status] AS column1, [Invoice_Date], [Invoice_No] FROM [Task] WHERE ([PO_ID] = @PO_ID)">
                    <SelectParameters>
                        <asp:ControlParameter ControlID="GridView1" Name="PO_ID" PropertyName="SelectedValue" Type="Int32" />
                    </SelectParameters>
                </asp:SqlDataSource>
                <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Test_DatabaseConnectionString3 %>" SelectCommand="SELECT [PO_ID], [Username], [UserDate], [Cost], [_Status] AS column1, [Invoice_Date], [Task_Note], [Invoice_No] FROM [Task] WHERE ([PO_ID] = @PO_ID)">
                    <SelectParameters>
                        <asp:ControlParameter ControlID="GridView1" Name="PO_ID" PropertyName="SelectedValue" Type="Int32" />
                    </SelectParameters>
                </asp:SqlDataSource>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Test_DatabaseConnectionString3 %>" SelectCommand="SELECT [PO_ID], [Username], [UserDate], [PO_Note], [Invoice_No] FROM [PO_Table]"></asp:SqlDataSource>
<br />

您的问题是您正在为多个 GridView 使用一个 SqlDataSource。由于每个 GridView2 使用 SqlDataSource2,它们最终都具有相同的数据 - 最后一个 GridView2 绑定的数据。 SqlDataSources 在标记中设置时自动绑定,如下所示:DataSourceID="SqlDataSource2".

MSDN on SqlDataSources:

The Select method is automatically called by controls that are bound to the SqlDataSource when their DataBind method is called. If you set the DataSourceID property of a data-bound control, the control automatically binds to data from the data source, as required.

这意味着当您在 GridView1_RowDataBound 中更改 SqlDataSource2 的 where 子句时,您的所有 GridView2 都将与该新过滤器绑定。

要解决此问题,请不要对 GridView2 使用 SqlDataSource。相反,使用它们自己的数据集单独绑定它们。

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        GridView gv2 = (GridView)e.Row.FindControl("GridView2");

        string connString = @"your connection string here";
        string query = "select * from dbo.task where PO_ID = " + e.Row.Cells[0].Text;

        SqlConnection conn = new SqlConnection(connString);        
        SqlCommand cmd = new SqlCommand(query, conn);
        conn.Open();

        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        da.Fill(dt);
        conn.Close();
        da.Dispose();

        gv2.DataSource = dt;
        gv2.DataBind();
    }
}

同样,我需要强调SQL Injection这样做时要小心。