tag route page net asp asp.net sql sql-server repeater

asp.net - route - Repetidores anidados y parámetros SqlDataSource



asp route tag helper (5)

Creo que la llamada a FindControl devuelve un valor nulo porque primero debe llamar a FindControl en el repetidor anidado y luego llamar a FindControl en el repetidor devuelto.

Repeater rpt = (Repeater)e.Item.FindControl("rptNested"); SqlDataSource s = (SqlDataSource)rpt.FindControl("InnerDataSource");

Estoy usando repetidores anidados para construir una tabla por razones que no discutiré aquí, pero lo que quiero hacer es tener dos fuentes de datos, una para el repetidor de nivel superior que corresponderá a las filas, y otra para el segundo nivel repetidor que devolverá celdas dentro de una fila.

Lo que me pregunto, sin embargo, es si de alguna manera puedo especificar un parámetro en el origen de datos del repetidor anidado que se establece un campo en los resultados del primer origen de datos?

¿Puedo establecer un parámetro para el valor de una expresión de enlace de datos?

La razón por la que quiero hacer esto es tener dos procedimientos almacenados. Cuando la página está cargada tengo un parámetro de sesión que puedo usar para ejecutar el primer procedimiento almacenado, sin embargo, para el segundo procedimiento almacenado, necesito asociar un valor de cada instancia del repetidor de nivel superior con una llamada al segundo procedimiento almacenado con un valor de parámetro diferente.


Creo que la mejor manera sería manejar el evento ItemDataBound del repetidor externo, encontrar el control interno de DataSource y establecer un parámetro Select para él.

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(); }

Para ver un ejemplo con DataList, consulte los inicios rápidos de ASP.NET aquí.

PD: Consulte la respuesta de Tony a continuación para una corrección importante del fragmento presentado anteriormente. En particular, sería esencial verificar el ItemType del RepeaterItem actual. Alternativamente, es una práctica excelente comprobar siempre si hay nulos en cada objeto.


Es posible que desee examinar una técnica que reducirá la cantidad de llamadas sproc. Es posible devolver resultados múltiples desde el mismo procedimiento almacenado. El conjunto de datos .net tiene la capacidad de definir relaciones entre tablas de datos múltiples, por lo que es fácil tomar un datarow en una tabla y obtener todos los nodos secundarios en otra tabla de datos. Ex:

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

Luego, desde cualquier datarow en TABLE_A, puedes acceder a todos los niños de esta manera:

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

Esto es más eficiente y en mi humilde opinión es más fácil también. De esta forma, no es necesario que cuente con llamadas sproc en los controladores de eventos para su repetidor.


Hice esto usando un HiddenField para almacenar un valor para usar como parámetro más adelante. Obtiene el trabajo hecho.

<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>


La respuesta de Cerebrus funciona, excepto que hay una captura. Obtendrás excepciones nulas a menos que sigas las reglas de esta pregunta, creo:

¿Cómo acceder al elemento vinculado a datos durante ItemDataBound?

Básicamente, debo verificar que el ítem en cuestión sea un ítem o un ítem alterno, de lo contrario los encabezados y los pies de página causarán problemas.

Editar: También recibí un error al intentar usar FindControl para obtener el DataSource. FindControl devolvió un nulo así que cuando accedí a la fuente de datos, recibí una segunda excepción nula. Así que terminé simplemente accediendo al objeto directamente. El origen de datos se declara en el archivo de diseñador de todos modos. Así que con esto, finalmente conseguí que los repetidores anidados funcionaran.

// 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(); }