Carga y selección de datos en tablas relacionadas empleando AJAX DropDownExtender y SqlDataSource (III)

Selección de registro en tabla relacionada


Al finalizar la segunda parte de este artículo habíamos dejado a nuestro control DropDownExtender pendiente de añadirle una funcionalidad, consistente en obtener un registro de la tabla DimProductCategory cada vez que hiciéramos una selección en la lista desplegable. Dado que el DropDownExtender lo llenábamos con los registros de la tabla DimProductSubcategory, el medio de obtener el registro de la tabla relacionada pasa por utilizar el campo ProductCategoryKey, presente en ambas tablas, y que establece dicha relación, como vemos en el siguiente esquema.



El efecto que perseguimos es el siguiente: al seleccionar un elemento de la lista, obtenemos el valor del campo ProductSubcategoryKey, el cual representa la clave primaria de la tabla DimProductSubcategory. Este dato lo habíamos añadido previamente al construir la lista de elementos del DropDownExtender, asignando a la propiedad ID de cada LinkButton una cadena compuesta por el prefijo «lnk_» más el valor del mencionado campo, que tomábamos de la fila en curso correspondiente al DataView que contenía los registros de la tabla.


 


// recorrer las filas de datos…
for (int nIndice = 0; nIndice < dvDimProductSubcategory.Count; nIndice++)
{
// …para cada registro
// crear un elemento en la lista desplegable (panel de lista)
oDataRowView = dvDimProductSubcategory[nIndice];

// cada elemento de la lista desplegable será un control LinkButton
oLinkButton = new LinkButton();
oLinkButton.ID = «lnk_» + (int)oDataRowView[«ProductSubcategoryKey»];
//….
//….


 

De esta forma, al hacer clic sobre uno de los LinkButton de la lista, en el manipulador de su evento Click, convertiremos la propiedad LinkButton.ID a un array de cadenas, recuperando la clave del registro desde la segunda posición de dicho array, tal y como vemos a continuación.

 

 

protected void LinkButton_Click(object sender, EventArgs e)
{
//….
// obtener a partir del identificador del elemento seleccionado
// el código del registro de la tabla DimProductSubcategory
string sProductSubcategoryKey = oLinkButton.ID.Split(new char[] { ‘_’ })[1];
//….

El siguiente paso consistirá en posicionarnos sobre el registro de la tabla DimProductSubcategory utilizando el valor recién obtenido. Para ello volveremos a obtener un DataView del  SqlDataSource que contiene dicha tabla, aplicándole un filtro basado en el valor del registro a localizar.


 


protected void LinkButton_Click(object sender, EventArgs e)
{
//….
// obtener a partir del identificador del elemento seleccionado
// el código del registro de la tabla DimProductSubcategory
string sProductSubcategoryKey = oLinkButton.ID.Split(new char[] { ‘_’ })[1];
//….
// recuperar del SqlDataSource correspondiente a la tabla DimProductSubcategory
// una vista con sus registros
DataView dvDimProductSubcategory = (DataView)this.dsrDimProductSubcategory.Select(new DataSourceSelectArguments());

// aplicar a la vista un filtro para obtener
// el registro seleccionado en la lista desplegable
dvDimProductSubcategory.RowFilter = «ProductSubcategoryKey = « + sProductSubcategoryKey;
//….
}


Ahora que ya estamos situados en la fila que queríamos de DimProductSubcategory, necesitamos obtener el registro relacionado de la tabla DimProductCategory mostrando sus valores en la página.


Para conseguir nuestro propósito agregaremos al diseño del WebForm un nuevo componente SqlDataSource basado en una consulta contra la tabla DimProductCategory. Puesto que solamente necesitaremos obtener un registro de dicha tabla en cada ocasión, añadiremos a este origen de datos un parámetro de filtro que nos sirva para acotar el resultado a una única fila.


Adicionalmente insertaremos en la página sendos controles Label y TextBox, cuyo fin consistirá en visualizar la información del registro de DimProductCategory seleccionado.


Para organizar adecuadamente todo el conjunto de controles que hemos incluido en la página utilizaremos una tabla, quedando la parte correspondiente al diseño de nuestro WebForm como vemos en el siguiente código fuente.


 


<form id=»form2″ runat=»server»>

<asp:ScriptManager ID=»ScriptManager1″ runat=»server» />

<asp:SqlDataSource ID=»dsrDimProductSubcategory» runat=»server»
ConnectionString=»Data Source=localhost;Initial Catalog=AdventureWorksDW;Persist Security Info=True;User ID=sa;Password=123sa456;»
SelectCommand=»SELECT * FROM DimProductSubcategory» />

<asp:SqlDataSource ID=»dsrDimProductCategory» runat=»server»
ConnectionString=»Data Source=localhost;Initial Catalog=AdventureWorksDW;Persist Security Info=True;User ID=sa;Password=123sa456;»
SelectCommand=»SELECT * FROM DimProductCategory»
FilterExpression=»ProductCategoryKey = ‘{0}'»>
<FilterParameters>
<asp:Parameter Name=»parProductCategoryKey» />
</FilterParameters>
</asp:SqlDataSource>

<div>
<asp:UpdatePanel ID=»pnlUpdatePanel» runat=»server»>
<ContentTemplate>
<table border=»1″>
<tr>
<td width=»240″ bgcolor=»#FFFFCC»>
<asp:TextBox ID=»txtTituloLista» runat=»server» Text=»Seleccionar artículo» Width=»200px» />
<br />
<asp:Panel ID=»pnlElementosLista» runat=»server» Width=»200px» />
<cc1:DropDownExtender ID=»DropDownExtender1″ runat=»server» DropDownControlID=»pnlElementosLista»
TargetControlID=»txtTituloLista» />
</td>
<td width=»350″ bgcolor=»#99FFCC»>
<asp:Label ID=»Label1″ runat=»server» Text=»ProductCategoryKey: « />
<asp:TextBox ID=»txtProductCategoryKey» runat=»server» Height=»22px» Width=»35px» />
<br />
<br />
<asp:Label ID=»Label2″ runat=»server» Text=»SpanishProductCategoryName: « />
<asp:TextBox ID=»txtSpanishProductCategoryName» runat=»server» Width=»100px» />
<br />
<br />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>


Únicamente nos queda escribir en el evento Click del LinkButton, la operación encargada de pasar al parámetro de filtro del objeto SqlDataSource asociado a la tabla DimProductCategory, el valor de búsqueda para la misma, tras lo cual obtendremos un DataView con el registro localizado. Los valores de este registro los traspasaremos a los controles de la página. A continuación podemos ver al completo el código de este evento.


 


protected void LinkButton_Click(object sender, EventArgs e)
{
// al hacer clic en un elemento de la lista
// mostrar el texto del elemento
// en el TextBox que sirve para desplegarla
LinkButton oLinkButton = ((LinkButton)sender);
this.txtTituloLista.Text = oLinkButton.Text;

// obtener a partir del identificador del elemento seleccionado
// el código del registro de la tabla DimProductSubcategory
string sProductSubcategoryKey = oLinkButton.ID.Split(new char[] { ‘_’ })[1];

// recuperar del SqlDataSource correspondiente a la tabla DimProductSubcategory
// una vista con sus registros
DataView dvDimProductSubcategory = (DataView)this.dsrDimProductSubcategory.Select(new DataSourceSelectArguments());

// aplicar a la vista un filtro para obtener
// el registro seleccionado en la lista desplegable
dvDimProductSubcategory.RowFilter = «ProductSubcategoryKey = « + sProductSubcategoryKey;

// obtener el registro relacionado de la tabla DimProductCategory:
// —————————————————————
// aplicar como filtro al objeto SqlDataSource de la tabla DimProductCategory
// el valor del campo ProductCategoryKey de la vista DimProductSubcategory
this.dsrDimProductCategory.FilterParameters[«parProductCategoryKey»].DefaultValue =
dvDimProductSubcategory[0][«ProductCategoryKey»].ToString();

// recuperar la vista de la tabla DimProductCategory
// conteniendo el registro filtrado y mostrarlo en los
// controles de la página
DataView dvDimProductCategory = (DataView)this.dsrDimProductCategory.Select(new DataSourceSelectArguments());
this.txtProductCategoryKey.Text = dvDimProductCategory[0][«ProductCategoryKey»].ToString();
this.txtSpanishProductCategoryName.Text = dvDimProductCategory[0][«SpanishProductCategoryName»].ToString();
}


Al volver a ejecutar la aplicación, la selección de un elemento de la lista mostrará los valores del registro de la tabla relacionada en el resto de controles de la página.


 



Tras estos últimos ajustes podemos dar por concluido el desarrollo del ejemplo, cuyo código fuente se puede descargar en este enlace. No obstante, existe un aspecto que dejaremos para una última entrega de este artículo, consistente en un modo alternativo de configurar las propiedades visuales de la lista desplegable.


Un saludo.

4 Comentarios

  1. anonymous

    Tengo una duda simple prero que no eh podido resolver. Como traigo un solo dato que se muestre en un textbox mediante un sqldatasource mi base esta en oracle. Les agradecira mucho me ayudaran.

  2. lmblanco

    Hola Claudia

    Si he comprendido bien, lo que necesitas es recuperar, mediante un SqlDataSource, un único valor que asignarás a un control TextBox. Yo no he utilizado Oracle, pero en el siguiente enlace tienes un pequeño tutorial de conexión a este tipo de bases de datos utilizando SqlDataSource.

    http://msdn.microsoft.com/es-es/library/92ceczx1(VS.80).aspx

    Y en cuanto a la parte del código, a continuación te adjunto un ejemplo (la base de datos es SQL Server) que conecta con un origen de datos y obtiene, de un registro, el valor de un campo.

    Para seleccionar un único registro utilizamos dentro del control SqlDataSource, la propiedad FilterExpression y la colección FilterParameters, donde creamos un parámetro.

    Pasando al code-behind, asignamos el valor de búsqueda al parámetro, ejecutamos la consulta del SqlDataSource, y recuperamos el resultado en un DataView, del que extraemos el valor del campo y lo pasamos al TextBox.

    //—————————







    ============================
    protected void btnConsulta_Click(object sender, EventArgs e)
    {
    this.dsrDatos.FilterParameters[«parGeographyKey»].DefaultValue = this.txtGeographyKey.Text;
    DataView dvDimGeography = (DataView)this.dsrDatos.Select(new DataSourceSelectArguments());
    this.txtCity.Text = dvDimGeography[0][«City»].ToString();
    }
    //—————————

    Espero que te sirva para resolver el problema.

    Un saludo.
    Luismi

  3. anonymous

    eso es interesante, peor en ese caso el script estaria entre el codigo html.. y si nesecito hacerlo en 3 capas con aspnet como seria ??

  4. lmblanco

    Hola gitto

    Gracias por leer el artículo 8-).

    En esta situación que mencionas, una posible opción podría consistir en mover las operaciones de manipulación de datos que realizan la selección de los registros en las tablas a una clase que podrías tener como un componente, y que este se encargara de enviarle los datos ya seleccionados a la parte de interfaz de usuario.

    Un saludo.

Responder a Cancelar respuesta

Tema creado por Anders Norén