[英]Fill nested repeaters in a table
我在另一个中继器内有一个中继器。 如何在内部中继器中显示db中的所有字段(姓)。 在函数outerRepeater_ItemDataBound
,无法识别DataSource
。 我不知道确切要为特定名称选择所有姓氏的位置。
我在repeater.ascx中有这个:
<form id="form1" runat="server">
<div>
<asp:Repeater runat="server" ID="outerRepeater" OnItemDataBound="outerRepeater_ItemDataBound">
<HeaderTemplate>
<table>
<td><th>Name:</th></td>
<td><th>Surname:</th></td>
</table>
</HeaderTemplate>
<ItemTemplate>
<h3><%#DataBinder.Eval(Container.DataItem,"Name")%></h3>
<asp:Repeater runat="server" ID="innerRepeater" >
<ItemTemplate>
<%#Eval("Surname") %>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
</div>
</form>
这在repeater.ascx.cs中
public partial class Repeater : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
outerRepeater.DataSource = GetDataSource();
outerRepeater.DataBind();
}
private DataTable GetDataSource()
{
SqlConnection myConnection = new SqlConnection(@"my connection string");
SqlDataAdapter myCommand = new SqlDataAdapter("SELECT Distinct Name FROM Person ORDER BY Name ", myConnection);
DataTable dt = new DataTable();
myCommand.Fill(dt);
myConnection.Close();
return dt;
}
private void Page_Init(object sender, EventArgs e)
{
InitializeComponent();
}
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
protected void outerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
Repeater innerRepeater = e.Item.FindControl("innerRepeater") as Repeater;
DataTable dt = GetSurname();
innerRepeater.DataSource = dt;//here isn't su
innerRepeater.DataBind();
}
}
private DataTable GetSurname()
{
SqlConnection myConnection = new SqlConnection(@"my connection string");
SqlDataAdapter da = new SqlDataAdapter("Select Surname from Person ", myConnection);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
我不确定您是否真的需要在后台代码中设置Page_Load
事件处理程序。 使用默认页面设置,它将自动连接。
仅当将PagesSection.AutoEventWireup设置为false时,才需要手动设置它。
可以使用Repeater创建一个表- 如何在ASP.Net Repeater中创建三列表 ,但是需要使用正确设置的表标记进行一些不同的标记:
<asp:Repeater runat="server" ID="outerRepeater" OnItemDataBound="outerRepeater_ItemDataBound">
<HeaderTemplate>
<table>
<thead>
<th>Name:</th>
<th>Surname:</th>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<h3><%#DataBinder.Eval(Container.DataItem,"Name")%></h3>
</td>
<td>
<asp:Repeater runat="server" ID="innerRepeater" >
<ItemTemplate>
<%#Eval("Surname") %>
</ItemTemplate>
</asp:Repeater>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
而且,也许GridView是手动创建表的更好选择。
您显然会得到所有姓氏,因为Select Surname from People
中Select Surname from People
不会过滤任何内容-它只会选择所有项。 为了实现所需的功能,您将必须添加一些WHERE子句 ,该子句将按与当前行关联的名称进行过滤。 可以通过outerRepeater_ItemDataBound
处理程序中的e.Item.DataItem
获得Name
。
protected void outerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
Repeater innerRepeater = e.Item.FindControl("innerRepeater") as Repeater;
String name = ((DataRowView)e.Item.DataItem)[0].ToString();
DataTable dt = GetSurname(name);
innerRepeater.DataSource = dt;//here isn't su
innerRepeater.DataBind();
}
}
private DataTable GetSurname(String name)
{
using (SqlConnection myConnection = new SqlConnection(@"Data Source=(LocalDb)\v11.0; Database = TSQL2012"))
{
using (SqlDataAdapter da = new SqlDataAdapter("Select Surname from Person WHERE Name = @name", myConnection))
{
da.SelectCommand.Parameters.AddWithValue("@name", name);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
}
当您在连接上调用Close
方法时,最好使用using
子句,就像在先前代码示例中使用的那样,因为using
可以确保无论发生什么情况,连接都将被确定关闭。 这同样适用于SqlDataAdapter
,但是我不知道它是实际上必需的还是只是一个很好的经验法则。
多个SQL请求,尤其是在所有必需信息都直接相关的情况下,可能会导致非常差的性能。 您可以获取所有名称和姓氏以在页面中对其进行处理,也可以应用最佳方式来串联/聚合字符串以获取具有所有所需数据的单个数据表:
ASPX:
<asp:Repeater runat="server" ID="outerRepeater">
...
<ItemTemplate>
<tr >
<td>
<h3><%#DataBinder.Eval(Container.DataItem,"Name")%></h3>
</td>
<td>
<label><%#DataBinder.Eval(Container.DataItem,"ConcatenatedSurnames")%></label>
</td>
</tr>
</ItemTemplate>
代码隐藏:
private const String SelectCommand = @"
WITH Partitioned AS
(
SELECT Name,
Surname,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Name) AS NameNumber,
COUNT(*) OVER (PARTITION BY Name ORDER BY Name) AS NameCount
FROM Person
),
Concatenated AS
(
SELECT Name,
CAST(Surname AS nvarchar) AS ConcatenatedSurnames,
NameNumber,
NameCount
FROM Partitioned
WHERE NameNumber = 1
UNION ALL
SELECT
P.Name,
CAST(C.ConcatenatedSurnames + ', ' + P.Surname AS nvarchar),
P.NameNumber,
P.NameCount
FROM Partitioned AS P
INNER JOIN Concatenated AS C
ON P.Name = C.Name AND
P.NameNumber = C.NameNumber + 1
)
SELECT
Name,
ConcatenatedSurnames
FROM Concatenated
WHERE NameNumber = NameCount";
private DataTable GetDataSource()
{
using (SqlConnection myConnection = new SqlConnection(@"Data Source=(LocalDb)\v11.0; Database = TSQL2012"))
{
using (SqlDataAdapter myCommand = new SqlDataAdapter(SelectCommand, myConnection))
{
DataTable dt = new DataTable();
myCommand.Fill(dt);
return dt;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.