Програмен избор на SqlDataSource повторител в повторител

Имам страница с Repeater, която итерира списък на персонализирана структура. ItemTemplate има Repeater, прикачен към SqlDataSource, който е сравнително чист и ще бъде попълнен с информация от структурата в кода отзад, където клаузата 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>

Опитах се да използвам DataBinding и Selecting на SqlDataSource и ItemDataBound на външния Repeater:

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, комбиниран с дадените параметри и получавам правилните резултати в Server Manager, дори направих нов SQLDataSource с всичко твърдо кодирано и това също работи добре. Докато можех да копирам и поставям с твърдо кодирани sqlDataSources, това проваля голяма част от смисъла на програмирането (въпреки че щях да съм приключил с това досега.)

Мисля, че това е свързано с жизнения цикъл на страницата, но не мога да разбера какво би било. Възможно ли е дори да се използва един източник на данни за множество итерации? Обърнете внимание, че това се използва само за избиране на данни за показване, а не за други команди, така че не е нужно да се притеснявам за обратно изпращане.

(Осъзнавам, че това може да бъде значително опростено с използването на StoredProcedure; въпросната база данни обаче се поддържа от друго приложение и внедряването или гарантирането, че SP се внедрява всеки път, когато се добавя база данни, би било досадно, а това е единствената страница, която прави подобни неща.)


person Kodithic    schedule 28.09.2012    source източник


Отговори (1)


Отговорете на въпроса ми защо не.

След по-нататъшно тестване се оказва, че съм бил прав за жизнения цикъл на страницата, но по грешни причини. Правех първоначалното DataBinding към външния повторител в Page_Init; след това това ще извика вътрешния повторител за DataBinding, но е било твърде рано в жизнения цикъл за извличане на данните, въведени от потребителя за StatementDate и AccountIndex. Промяната на това на Page_Load поправи този проблем.

След това реших да работя с предположението, че използването на един и същ обект SqlDataSource за множество RepeaterItems и промяната му няма да проработи (въпреки че все още не съм сигурен в това), така че преминах към пълно създаване и обвързване на SqlDataSource в codebehind. В крайна сметка 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();
    } 
}
person Kodithic    schedule 28.09.2012