Программный выбор в репитере в репитере SqlDataSource

У меня есть страница с повторителем, который выполняет итерацию по списку настраиваемой структуры. ItemTemplate имеет повторитель, прикрепленный к 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
}

(Выбор выполняется четыре раза, тогда как я бы подумал, что должно быть только два, по одному разу для каждого внешнего элемента Repeater.)

Я беру окончательный CommandText в сочетании с заданными параметрами и получаю правильные результаты в диспетчере серверов, я даже создал новый SQLDataSource со всем жестко запрограммированным, и он тоже работал нормально. Хотя я мог копировать и вставлять с помощью жестко запрограммированных sqlDataSources, это лишает многих смысла программирования (хотя к настоящему времени я бы с этим покончил).

Я думаю, что это связано с жизненным циклом страницы, но я не могу понять, что это будет. Возможно ли вообще использовать один источник данных в течение нескольких итераций? Обратите внимание, что это используется только для выбора данных для отображения, а не для каких-либо других команд, поэтому мне не нужно беспокоиться о обратной передаче.

(Я понимаю, что это можно значительно упростить с помощью StoredProcedure; однако данная база данных поддерживается другим приложением, и развертывание или обеспечение развертывания SP всякий раз, когда добавляется база данных, будет раздражать, а это единственная страница, делающая такие вещи.)


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


Ответы (1)


Ответьте на мой собственный вопрос, почему бы и нет.

После дальнейшего тестирования выяснилось, что я был прав в отношении жизненного цикла страницы, но по неправильным причинам. Я выполнял начальную привязку данных к внешнему повторителю в Page_Init; тогда это вызовет внутренний Repeater для DataBinding, но в жизненном цикле было слишком рано извлекать данные, введенные пользователем для StatementDate и AccountIndex. Изменение этого параметра на Page_Load устранило эту проблему.

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