Вложенные повторители и параметры SqlDataSource

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

Однако мне интересно, могу ли я как-то указать параметр в источнике данных вложенного повторителя, который задает поле в результатах из первого источника данных?

Могу ли я установить параметр в значение выражения привязки данных?

Я хочу сделать это потому, что у меня есть две хранимые процедуры. Когда страница загружена, у меня есть параметр сеанса, который я могу использовать для запуска первой хранимой процедуры, однако для второй хранимой процедуры мне нужно связать значение из каждого экземпляра повторителя верхнего уровня с вызовом второй хранимой процедуры. с другим значением параметра.

5 ответов

Решение

Я думаю, что лучшим способом было бы обработать событие ItemDataBound внешнего повторителя, найти внутренний элемент управления DataSource и установить для него SelectParameter.

    void MyOuterRepeater_ItemDataBound(Object sender, RepeaterItemEventArgs e) 
    {
    // Find the Inner DataSource control in this Row.
    SqlDataSource s = (SqlDataSource)e.Item.FindControl("InnerDataSource");

    // Set the SelectParameter for this DataSource control
    // by re-evaluating the field that is to be passed.
    s.SelectParameters["MyParam"].DefaultValue = DataBinder.Eval(e.Item.DataItem, "MyFieldValueToPass").ToString();
    }

Для примера использования DataList, ознакомьтесь с кратким обзором ASP.NET здесь

PS: Пожалуйста, смотрите ответ Тони ниже для важной коррекции к представленному выше фрагменту. Примечательно, что было бы важно проверить ItemType текущего RepeaterItem. Кроме того, это отличная практика - всегда проверять наличие нулей на каждом объекте.

Я сделал это с помощью HiddenField, чтобы сохранить значение для использования в качестве параметра позже. Получает работу сделано.

<asp:SqlDataSource ... />
<asp:Repeater ...>
    <ItemTemplate>

        <asp:HiddenField ID="txtOuterID" runat="server" Value='<%# Eval("ID") %>' Visible="false" />

        <asp:SqlDataSource ...>
            <SelectParameters>
                <asp:ControlParameter Name="OuterID" Type="Int32" ControlID="txtOuterID" PropertyName="Value" />
            </SelectParameters>
        </asp:SqlDataSource>

        <asp:Repeater ...>

    </ItemTemplate>
</asp:Repeater>

Возможно, вы захотите изучить технику, которая позволит уменьшить количество вызовов sproc. Можно вернуть несколько наборов результатов из одной хранимой процедуры. Набор данных.net имеет возможность определять отношения между несколькими таблицами данных, что позволяет легко брать данные в одной таблице и получать все дочерние узлы в другой таблице данных. Пример:

exampleData.Relations.Add(New DataRelation("FOO_RELATION", exampleData.Tables["TABLE_A"].Columns["ID"], exampleData.Tables["TABLE_B"].Columns["PARENT_ID"]));

Затем из любого datarow в TABLE_A вы можете получить доступ ко всем детям, как это:

DataRow[] childRows = row.GetChildRows("FOO_RELATION");

Это более эффективно, и IMHO также проще. Таким образом, вам не нужно отправлять вызовы sproc в обработчики событий для вашего ретранслятора.

Ответ Церебра работает, за исключением того, что есть один улов. Вы получите нулевые исключения, если не будете следовать правилам этого вопроса, я думаю:

Как получить доступ к элементу, привязанному к данным во время ItemDataBound?

По сути, я должен проверить, чтобы убедиться, что рассматриваемый элемент является элементом или альтернативным элементом, в противном случае верхние и нижние колонтитулы могут вызвать проблемы.

Изменить: я также получил ошибку при попытке использовать FindControl для получения источника данных. FindControl возвратил ноль, поэтому, когда я пошел к источнику данных, я получил второе нулевое исключение. В итоге я просто получил прямой доступ к объекту. В любом случае источник данных объявлен в файле конструктора. Итак, с этим я наконец-то заставил работать вложенные репитеры.

// Find the Inner DataSource control in this Row.

if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == 
    ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.EditItem)
{
    CellsDataSource.SelectParameters["testRunID"].DefaultValue = 
        DataBinder.Eval(e.Item.DataItem, "TestRunID").ToString();
}

Я думаю, что вызов FindControl возвращает ноль, потому что сначала нужно вызвать FindControl для вложенного повторителя, а затем вызвать FindControl для возвращенного повторителя.

Repeater rpt  = (Repeater)e.Item.FindControl("rptNested");
SqlDataSource s = (SqlDataSource)rpt.FindControl("InnerDataSource");
Другие вопросы по тегам