嵌套的 Gridview 冗余值
Nested Gridview redundant values
我有 2 个网格视图。 Gridview1
、Gridview2
。
两者都有共同领域 "ID"
当我 Select Gridview1
(ID=1
) 中的第一行时,Gridview2
中 ID=1
的值显示在嵌套区域中,但值显示在 Gridview1 的每一行中。当我删除 "select" 时,Gridview2
没有任何显示。
当我打开页面时,我希望显示 Gridview1
,然后嵌套 Gridview2
显示来自 Gridivew1
的个人 ID 的内容。我不希望 select 看到所有内容,我只希望两个表都显示它们的数据。
我做了什么:
- 添加
Gridview1
- select 我的专栏显示使用 sql 数据源
- 编辑列(添加了一些绑定字段和一个模板字段来表示
Gridview2
)
- 编辑模板
- 已在模板中插入
Gridview2
- select 我的专栏
- 其中ID=
Gridview1
的控件值为ID
(Gridview1.SelectedValue
)
- 将
Gridview1
的DataKeyNames
设置为ID
后面的代码:
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"
.
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这样做时要小心。
我有 2 个网格视图。 Gridview1
、Gridview2
。
两者都有共同领域 "ID"
当我 Select Gridview1
(ID=1
) 中的第一行时,Gridview2
中 ID=1
的值显示在嵌套区域中,但值显示在 Gridview1 的每一行中。当我删除 "select" 时,Gridview2
没有任何显示。
当我打开页面时,我希望显示 Gridview1
,然后嵌套 Gridview2
显示来自 Gridivew1
的个人 ID 的内容。我不希望 select 看到所有内容,我只希望两个表都显示它们的数据。
我做了什么:
- 添加
Gridview1
- select 我的专栏显示使用 sql 数据源
- 编辑列(添加了一些绑定字段和一个模板字段来表示
Gridview2
) - 编辑模板
- 已在模板中插入
Gridview2
- select 我的专栏
- 其中ID=
Gridview1
的控件值为ID
(Gridview1.SelectedValue
) - 将
Gridview1
的DataKeyNames
设置为ID
后面的代码:
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"
.
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这样做时要小心。