我有一个带有Repeater的页面,它遍历一个自定义结构的List。 ItemTemplate有一个附加到SqlDataSource的Repeater,它非常简单,并且将填充来自代码隐藏中struct的信息,其中WHERE子句的不同之处仅在于将<
更改为>
。 StatementDate和AccountIndex是用户填写以定义信息的TextBox和DDL(分别)。但是,所有尝试设置各种sqlDataSource详细信息的程序都会导致返回任何内容(错误或行。)
<asp:Repeater ID="SelectedRepeater" runat="server" onitemdatabound="SelectedRepeater_ItemDataBound">
<ItemTemplate>
<asp:Repeater ID="EntryRepeater" DataSourceID="RecordsDataSource" runat="server" OnItemDataBound="EntryRepeater_ItemDataBound">
<ItemTemplate>
<tr>
<td>
<%# Eval("TrxDate", StandardDate) %>
<span class="error"><%# ShowExclamation(Eval("DateCleared")) %></span>
</td>
<td><%# Eval("Reference")%></td>
<td><%# Eval("VendorName")%></td>
<td><%# Eval("Memo")%></td>
<td class="money"><%# Eval("Amount","{0:n2}")%></td>
</tr>
</ItemTemplate>
</asp:Repeater>
<asp:SqlDataSource ConnectionString="<%=ConnectionString(ActiveClient)%>" ProviderName="System.Data.SqlClient" OnSelecting="RecordsDataSource_Selecting" ID="RecordsDataSource" OnDataBinding="RecordsDataSource_DataBinding" runat="server">
<SelectParameters>
<asp:ControlParameter ControlID="StatementDate" DefaultValue="2/2/1900" Name="StatementDate"
PropertyName="Text" />
<asp:ControlParameter ControlID="AccountIndex" DefaultValue="" Name="AccountIndex"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:Repeater>
我尝试过使用SqlDataSource的DataBinding和选择以及外部Repeater的ItemDataBound:
protected void RecordsDataSource_DataBinding(object sender, EventArgs e) {
_currentCommand = String.Format(_standardSelect, Eval("WhereClause").ToString());
SqlDataSource sds = sender as SqlDataSource;
sds.SelectCommandType = SqlDataSourceCommandType.Text;
sds.SelectCommand = String.Format(_standardSelect, Eval("WhereClause").ToString());
}
protected void SelectedRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if (IsListItemRow(e.Item)) {
SqlDataSource sds = (e.Item.FindControl("RecordsDataSource") as SqlDataSource);
sds.SelectCommand = String.Format(_standardSelect, ((PrintSection)e.Item.DataItem).WhereClause);
sds.Select(DataSourceSelectArguments.Empty);
}
}
protected void RecordsDataSource_Selecting(object sender, SqlDataSourceSelectingEventArgs e) {
e.Command.CommandText = _currentCommand; //set in DataBinding
}
(当我认为它应该只有两个时,选择被击中四次,每个外部中继器项目一次。)
我将最终的CommandText与给定的参数结合起来并在服务器管理器中获得正确的结果,我甚至创建了一个新的SQLDataSource,其中包含所有硬编码的内容,并且工作正常。虽然我可以使用硬编码的sqlDataSources进行复制粘贴,但这会破坏很多编程点(尽管我现在已经完成了这一点。)
我的想法是,这与页面生命周期有关,但我无法弄清楚它会是什么。在多次迭代中使用一个数据源是否可行?请注意,这仅用于选择要显示的数据,而不是用于任何其他命令,因此我不需要担心回发。
(我意识到使用StoredProcedure可以大大简化这一点;但是,有问题的数据库是由另一个应用程序维护的,每当添加数据库时部署或确保部署SP会很烦人,这是唯一一个做这种事情的网页。)
答案 0 :(得分:0)
回答我自己的问题为什么不呢。
经过进一步测试后发现我对页面生命周期是正确的,但出于错误的原因。我正在Page_Init
中对外部Repeater进行初始DataBinding;然后,这将调用内部Repeater进行DataBinding,但是在生命周期中检索用户为StatementDate和AccountIndex输入的数据还为时过早。将此更改为Page_Load
修复了该问题。
接下来,我决定假设为多个RepeaterItem使用相同的SqlDataSource对象并更改它不会起作用(虽然我仍然不确定),所以我切换到完全创建和绑定代码隐藏中的SqlDataSource。最后,ASP代码与问题中的相同,减去SqlDataSource,现在代码隐藏如下:
protected void SelectedRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if (IsListItemRow(e.Item)) { //checks for both Item and AlternateItem
SqlDataSource sds = new SqlDataSource(ConnectionString(ActiveClient),
String.Format(_standardSelect, ((PrintSection)e.Item.DataItem).WhereClause));
sds.SelectParameters.Add("StatementDate", StatementDate.Text);
sds.SelectParameters.Add("AccountIndex", AccountIndex.SelectedValue);
sds.Select(DataSourceSelectArguments.Empty);
Repeater innerRepeater = (e.Item.FindControl("EntryRepeater") as Repeater);
innerRepeater.DataSource = sds;
innerRepeater.DataBind();
}
}