Ahora vamos a mejorar el acceso a datos del ejercicio realizado en la publicación anterior.
Como dije en la parte 3, no es bueno tener el código de la interfaz de usuario y el código de acceso a los datos en la misma capa, siempre hace falta un poco de lógica o como veremos en este ejercicio una implementación que es más "económica" porque utiliza un DataReader (que es un componente conectado de ADO.NET) que nos permite obtener la información de la base de datos.
En este caso el objetivo es mejorar el acceso a datos de la publicación anterior; no es que la hecho en la publicación anterior esté mal, ocurre que se puede hacer lo mismo con menos recursos y eso se llama eficiencia.
Primero vamos a suprimir los orígenes de datos del formulario o página web que teníamos, de manera que queda algo como esto:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm4.aspx.cs" Inherits="ADO2.WebForm4" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>
Provincia</td>
<td>
<asp:DropDownList ID="ddlProvincia" runat="server" AutoPostBack="True"
onselectedindexchanged="ddlProvincia_SelectedIndexChanged">
</asp:DropDownList>
</td>
</tr>
<tr>
<td>
Departamento</td>
<td>
<asp:DropDownList ID="ddlDepartamento" runat="server" AutoPostBack="True"
onselectedindexchanged="ddlDepartamento_SelectedIndexChanged">
</asp:DropDownList>
</td>
</tr>
<tr>
<td>
Localidad</td>
<td>
<asp:DropDownList ID="ddlLocalidad" runat="server" AutoPostBack="True"
onselectedindexchanged="ddlLocalidad_SelectedIndexChanged">
</asp:DropDownList>
</td>
</tr>
</table>
</div>
<asp:Label ID="lblResultado" runat="server" Text="Label"></asp:Label>
</form>
</body>
</html>
Observen que ahora los DropDownList solamente indican que se atrapa el evento de cambio del índice de selección. Todo estará en el código asociado.
En el archivo .aspx.cs vamos a incorporar el siguiente método:
1: /// <summary>
2: /// Enlace de datos personalizado
3: /// </summary>
4: protected void ProvinciaBind()
5: {
6: SqlConnection mySqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Postal"].ConnectionString);
7: mySqlConnection.Open();
8:
9: SqlCommand mySqlCommand = new SqlCommand();
10: mySqlCommand.Connection = mySqlConnection;
11: mySqlCommand.CommandText = "SELECT [ID], [Nombre] FROM [Provincia]";
12: mySqlCommand.CommandType = CommandType.Text;
13: SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
14:
15: ddlProvincia.DataSource = mySqlDataReader;
16: ddlProvincia.DataTextField = "Nombre";
17: ddlProvincia.DataValueField = "ID";
18: ddlProvincia.DataBind();
19:
20: mySqlDataReader.Close();
21: mySqlConnection.Close();
22: }
Este método utiliza un objeto del tipo SqlConnection que nos permite acceder al servidor donde se ejecuta el motor de base de datos y a la base de datos particular que se indica en la cadena de conexión que se obtiene del web.config. Se abre la conexión y luego se crea un objeto del tipo SqlCommand al que se indica que debe utilizar la conexión abierta y la sentencia SQL que debe ejecutar.
Luego se declara y crea un objeto del tipo SqlDataReader que se "llena" cuando se invoca el método ExecuteReader del comando. Este objeto, el reader se asocia como origen de datos del DropDownList, se indica cuáles son los campos que debe utilizar como texto y valor y finalmente se le pide al DropDownList que enlace los datos. Finalmente se "cierra" el reader y la conexión lo que libera los recursos del servidor SQL.
En el método Page_Load( ... ) se debe invocar a este método para que se pueda seleccionar una provincia. Por supuesto lo haremos solamente la primera vez que se cargue la página:
1: /// <summary>
2: /// Carga de la página
3: /// </summary>
4: /// <param name="sender">Referencia al objeto que ejecuta el evento</param>
5: /// <param name="e">Información del evento</param>
6: protected void Page_Load(object sender, EventArgs e)
7: {
8: if (!this.IsPostBack)
9: {
10: ProvinciaBind();
11: }
12: }
Ahora necesitamos un par de métodos que deberán cargar o "enlazar" los DropDownList de Departamentos y Localidades cuando se produzcan los cambios de índices de selección. A continuación están estos métodos:
1: /// <summary>
2: /// Enlace de datos personalizado para el Drop Down List (Departamento)
3: /// </summary>
4: protected void DepartamentoBind()
5: {
6: SqlConnection mySqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Postal"].ConnectionString);
7: mySqlConnection.Open();
8:
9: SqlCommand mySqlCommand = new SqlCommand();
10: mySqlCommand.Connection = mySqlConnection;
11: mySqlCommand.CommandText = "SELECT [ID], [Nombre] FROM [Departamento] WHERE ([idProvincia] = @idProvincia)";
12: mySqlCommand.CommandType = CommandType.Text;
13: mySqlCommand.Parameters.AddWithValue("@idProvincia", Int32.Parse(ddlProvincia.SelectedValue));
14: SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
15:
16: ddlDepartamento.DataSource = mySqlDataReader;
17: ddlDepartamento.DataTextField = "Nombre";
18: ddlDepartamento.DataValueField = "ID";
19: ddlDepartamento.DataBind();
20:
21: mySqlDataReader.Close();
22: mySqlConnection.Close();
23: }
Es bastante parecido al de las Provincias, solo que ahora se envía un parámetro que justamente es el código de la provincia actualmente seleccionada.
El de localidades es igual, pero aquí esta:
1: /// <summary>
2: /// Enlace de datos personalizado para el Drop Down List (Localidad)
3: /// </summary>
4: protected void LocalidadBind()
5: {
6: SqlConnection mySqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["Postal"].ConnectionString);
7: mySqlConnection.Open();
8:
9: SqlCommand mySqlCommand = new SqlCommand();
10: mySqlCommand.Connection = mySqlConnection;
11: mySqlCommand.CommandText = "SELECT [ID], [Nombre] FROM [Localidad] WHERE ([idDepartamento] = @idDepartamento)";
12: mySqlCommand.CommandType = CommandType.Text;
13: mySqlCommand.Parameters.Clear();
14: mySqlCommand.Parameters.AddWithValue("@idDepartamento", Int32.Parse(ddlDepartamento.SelectedValue));
15: SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
16:
17: ddlLocalidad.DataSource = mySqlDataReader;
18: ddlLocalidad.DataTextField = "Nombre";
19: ddlLocalidad.DataValueField = "ID";
20: ddlLocalidad.DataBind();
21:
22: mySqlDataReader.Close();
23: mySqlConnection.Close();
24: }
Ahora en los métodos que atrapan los eventos de cambio del índice de selección debemos indicar que ejecute estos métodos:
1: /// <summary>
2: /// Atrapa el cambio de selección en el Drop Down Lista (Provincia)
3: /// </summary>
4: /// <param name="sender">Referencia al objeto que ejecuta el evento</param>
5: /// <param name="e">Información del evento</param>
6: protected void ddlProvincia_SelectedIndexChanged(object sender, EventArgs e)
7: {
8: if (ddlProvincia.SelectedIndex != -1)
9: {
10: DepartamentoBind();
11: lblResultado.Text = "";
12: }
13: }
14: /// <summary>
15: /// Atrapa el cambio de selección en el Drop Down Lista (Departamento)
16: /// </summary>
17: /// <param name="sender">Referencia al objeto que ejecuta el evento</param>
18: /// <param name="e">Información del evento</param>
19: protected void ddlDepartamento_SelectedIndexChanged(object sender, EventArgs e)
20: {
21: if (ddlDepartamento.SelectedIndex != -1)
22: {
23: LocalidadBind();
24: lblResultado.Text = "";
25: }
26: }
27: /// <summary>
28: /// Atrapa el cambio de selección en el Drop Down Lista (Localidad)
29: /// </summary>
30: /// <param name="sender">Referencia al objeto que ejecuta el evento</param>
31: /// <param name="e">Información del evento</param>
32: protected void ddlLocalidad_SelectedIndexChanged(object sender, EventArgs e)
33: {
34: if (ddlLocalidad.SelectedIndex != -1)
35: {
36: lblResultado.Text = "Seleccionó " + ddlLocalidad.SelectedValue + " - " + ddlLocalidad.SelectedItem.Text;
37: }
38: }
Con esto hemos logrado, exactamente el mismo comportamiento que la publicación anterior solo que en esta oportunidad se tiene por un lado la interfaz de usuario y por otro lado el acceso a datos; además se consumen menos recursos dado que un DataReader es más chico y más rápido que un DataSet.
Espero que sirva.
Para leer fuera de línea: Un Poco de ADO NET - parte 4.pdf (42,82 kb)