Crear una capa de acceso a datos (VB)

por Scott Mitchell

Descargar PDF

En este tutorial comenzaremos desde el principio y crearemos la capa de acceso a datos (DAL), mediante DataSets tipados, para acceder a la información de una base de datos.

Introducción

Como desarrolladores web, nuestras vidas giran en torno al trabajo con datos. Creamos bases de datos para almacenar los datos, código para recuperarlos y modificarlos, y páginas web para recopilarlos y resumirlos. Este es el primer tutorial de una serie larga que explorará las técnicas para implementar estos patrones comunes en ASP.NET 2.0. Comenzaremos con la creación de una arquitectura de software compuesta por una capa de acceso a datos (DAL) mediante DataSets tipados, una capa de lógica de negocios (BLL) que aplica reglas de negocio personalizadas y una capa de presentación compuesta por páginas ASP.NET que comparten un diseño de página común. Una vez que se haya establecido esta base de back-end, pasaremos a los informes, en los que se muestra cómo mostrar, resumir, recopilar y validar datos de una aplicación web. Estos tutoriales están orientados a ser concisos y proporcionan instrucciones paso a paso con una gran cantidad de capturas de pantalla para guiarle visualmente por el proceso. Cada tutorial está disponible en las versiones de C# y Visual Basic e incluye una descarga del código completo usado. (Este primer tutorial es bastante largo, pero el resto se presentan en fragmentos mucho más digeribles).

En estos tutoriales usaremos una versión de Microsoft SQL Server 2005 Express Edition de la base de datos Northwind situada en el directorio App_Data. Además del archivo de base de datos, la carpeta App_Data también contiene los scripts SQL para crear la base de datos, en caso de que desee usar una versión de base de datos diferente. Si usa otra versión de SQL Server de la base de datos Northwind, deberá actualizar la configuración NORTHWNDConnectionString en el archivo Web.config de la aplicación. La aplicación web se creó con Visual Studio 2005 Professional Edition como un proyecto de sitio web basado en el sistema de archivos. Sin embargo, todos los tutoriales funcionarán igualmente bien con la versión gratuita de Visual Studio 2005, Visual Web Developer.

En este tutorial empezaremos desde el principio y crearemos la capa de acceso a datos (DAL), seguiremos con la creación de la capa de lógica empresarial (BLL) en el segundo tutorial, y trabajaremos en el diseño de la página y la navegación en el tercero. Los tutoriales después del tercero se basarán en la base establecida en los tres primeros. Tenemos mucho que cubrir en este primer tutorial, ¡así que ponga en marcha Visual Studio y empecemos!

Paso 1: Crear un proyecto web y conectarse a la base de datos

Para poder crear nuestra capa de acceso a datos (DAL), primero necesitamos crear un sitio web y configurar nuestra base de datos. Empiece por crear un nuevo sitio web basado en el sistema de archivos ASP.NET. Para ello, vaya al menú Archivo y elija Nuevo sitio web, mostrando el cuadro de diálogo Nuevo sitio web. Elija la plantilla sitio web de ASP.NET, establezca la lista desplegable Ubicación en Sistema de archivos, elija una carpeta para colocar el sitio web y establezca el idioma en Visual Basic.

Create a New File System-Based Web Site

Figura 1: creación de un nuevo sitio web basado en el sistema de archivos (haga clic para ver la imagen a tamaño completo)

Esto creará un sitio web con una página de ASP.NET Default.aspx, una carpeta App_Data y un archivo Web.config.

Con el sitio web creado, el siguiente paso es agregar una referencia a la base de datos en el Explorador de servidores de Visual Studio. Al agregar una base de datos al Explorador de servidores, puede agregar tablas, procedimientos almacenados, vistas, etc. desde Visual Studio. También puede ver los datos de tabla o crear sus propias consultas a mano o gráficamente a través del Generador de consultas. Además, al compilar los DataSets tipados para DAL, es necesario que apunte Visual Studio a la base de datos desde la que se deben construir los DataSets tipados. Aunque podemos proporcionar esta información de conexión en ese momento, Visual Studio rellena automáticamente una lista desplegable de las bases de datos ya registradas en el Explorador de servidores.

Los pasos para agregar la base de datos Northwind al Explorador de servidores dependen de si desea usar la base de datos SQL Server 2005 Express Edition en la carpeta App_Data o si tiene una configuración de servidor de base de datos de Microsoft SQL Server 2000 o 2005 que desea usar en su lugar.

Usar una base de datos en la carpeta App_Data

Si no tiene un servidor de bases de datos de SQL Server 2000 o 2005 para conectarse, o simplemente desea evitar tener que agregar la base de datos a un servidor de bases de datos, puede usar la versión SQL Server 2005 Express Edition de la base de datos Northwind que se encuentra en la carpeta App_Data del sitio web descargado (NORTHWND.MDF).

Se agrega automáticamente una base de datos situada en la carpeta App_Data al Explorador de servidores. Suponiendo que tiene SQL Server 2005 Express Edition instalado en el equipo, debería ver un nodo denominado NORTHWND.MDF en el Explorador de servidores, que puede expandir y explorar sus tablas, vistas, procedimiento almacenado, etc. (vea la figura 2).

La carpeta App_Data también puede contener archivos .mdb de Microsoft Access, que, al igual que sus homólogos de SQL Server, se agregan automáticamente al Explorador de servidores. Si no quiere usar ninguna de las opciones de SQL Server, siempre puede instalar aplicaciones y bases de datos de Northwind Traders y colocarlas en el directorio App_Data. Tenga en cuenta, sin embargo, que las bases de datos de Access no son tan enriquecidas como SQL Server y no están diseñadas para usarse en escenarios de sitio web. Además, un par de los más de 35 tutoriales utilizarán ciertas funciones a nivel de base de datos que no son compatibles con Access.

Conexión a la base de datos en un servidor de base de datos Microsoft SQL Server 2000 o 2005

Como alternativa, puede conectarse a una base de datos Northwind instalada en un servidor de bases de datos. Si el servidor de bases de datos aún no tiene instalada la base de datos Northwind, primero debe agregarla al servidor de bases de datos ejecutando el script de instalación incluido en la descarga de este tutorial.

Una vez que tenga instalada la base de datos, vaya al Explorador de servidores en Visual Studio, haga clic con el botón derecho en el nodo Conexiones de datos y elija Agregar conexión. Si no ve el Explorador de servidores, vaya al Explorador de vistas o servidores o presione Ctrl+Alt+S. Se abrirá el cuadro de diálogo Agregar conexión, donde puede especificar el servidor al que conectarse, la información de autenticación y el nombre de la base de datos. Una vez que haya configurado correctamente la información de conexión de la base de datos y haga clic en el botón Aceptar, la base de datos se agregará como un nodo debajo del nodo Conexiones de datos. Puede expandir el nodo de base de datos para explorar sus tablas, vistas, procedimientos almacenados, etc.

Add a Connection to Your Database Server's Northwind Database

Figura 2: Agregar una conexión a la base de datos Northwind del servidor de bases de datos

Paso 2: Crear la capa de acceso a datos

Cuando se trabaja con datos una opción es insertar la lógica específica de datos directamente en la capa de presentación (en una aplicación web, las páginas de ASP.NET componen la capa de presentación). Esto puede adoptar la forma de escribir código ADO.NET en la parte de código de la página ASP.NET o de utilizar el control SqlDataSource desde la parte de marcado. En cualquier caso, este enfoque acopla estrechamente la lógica de acceso a datos con la capa de presentación. Sin embargo, el enfoque recomendado es separar la lógica de acceso a datos de la capa de presentación. Esta capa independiente se conoce como capa de acceso a datos, DAL, para abreviar, y normalmente se implementa como un proyecto de biblioteca de clases independiente. Las ventajas de esta arquitectura en capas están bien documentadas (vea la sección "Lecturas adicionales" al final de este tutorial para obtener información sobre estas ventajas) y es el enfoque que tomaremos en esta serie.

Todo el código específico del origen de datos subyacente, como la creación de una conexión a la base de datos, la emisión de comandos SELECT, INSERT, UPDATE, DELETE, etc., debe ubicarse en la DAL. La capa de presentación no debe contener referencias a este código de acceso a datos, sino que debe realizar llamadas a la DAL para todas y todas las solicitudes de datos. Las capas de acceso a datos suelen contener métodos para acceder a los datos de base de datos subyacentes. La base de datos Northwind, por ejemplo, tiene las tablas Products y Categories que registran los productos en venta y las categorías a las que pertenecen. En nuestra DAL tendremos métodos como:

  • GetCategories(),, que devolverá información sobre todas las categorías
  • GetProducts(), que devolverá información sobre todos los productos
  • GetProductsByCategoryID(categoryID), que devolverá todos los productos que pertenecen a una categoría especificada
  • GetProductByProductID(productID), que devolverá información sobre un producto determinado

Estos métodos, cuando se invocan, se conectarán a la base de datos, emitirán la consulta adecuada y devolverán los resultados. La forma en que se devuelven estos resultados es importante. Estos métodos podrían devolver simplemente un DataSet o un DataReader poblado por la consulta a la base de datos, pero lo ideal sería que estos resultados se devolvieran utilizando objetos fuertemente tipados. Un objeto fuertemente tipado es uno cuyo esquema se define de forma rígida en tiempo de compilación, mientras que lo contrario, un objeto de tipo flexible, es uno cuyo esquema no se conoce hasta el tiempo de ejecución.

Por ejemplo, DataReader y DataSet (de forma predeterminada) son objetos de tipo flexible, ya que sus esquemas se definen mediante las columnas devueltas por la consulta de base de datos que se usan para rellenarlos. Para acceder a una columna determinada desde una DataTable de tipo flexible, es necesario usar la sintaxis como: DataTable.Rows(index)("columnName"). La escritura flexible de DataTable en este ejemplo se muestra por el hecho de que necesitamos tener acceso al nombre de columna mediante un índice ordinal de cadena. Una DataTable fuertemente tipada, por otro lado, tendrá cada una de sus columnas implementadas como propiedades, dando como resultado un código con el aspecto siguiente: DataTable.Rows(index).columnName.

Para devolver objetos fuertemente tipados, los desarrolladores pueden crear sus propios objetos empresariales personalizados o usar DataSets tipados. El desarrollador implementa un objeto de negocio como una clase cuyas propiedades suelen reflejar las columnas de la tabla de base de datos subyacente que representa el objeto de negocio. Un conjunto de datos tipado es una clase generada para usted por Visual Studio basada en un esquema de base de datos y cuyos miembros están fuertemente tipados de acuerdo con este esquema. El propio conjunto de datos tipado consta de clases que amplían las clases ADO.NET DataSet, DataTable y DataRow. Además de las DataTables fuertemente tipadas, los DataSets tipados incluyen ahora también TableAdapters, que son clases con métodos para poblar las DataTables del DataSet y propagar las modificaciones dentro de las DataTables de vuelta a la base de datos.

Nota:

Para obtener más información sobre las ventajas y desventajas de utilizar DataSets tipados frente a objetos de negocio personalizados, consulte Diseño de componentes de niveles de datos y paso de datos a través de niveles.

Usaremos DataSets fuertemente tipados para la arquitectura de estos tutoriales. En la figura 3 se muestra el flujo de trabajo entre las distintas capas de una aplicación que usa DataSets tipados.

All Data Access Code is Relegated to the DAL

Figura 3: Todo el código de acceso a los datos se relega al DAL (haga clic para ver la imagen a tamaño completo)

Creación de un DataSet tipado y un adaptador de tabla

Para empezar a crear nuestra DAL, empezamos agregando un DataSet tipado a nuestro proyecto. Para ello, haga clic con el botón derecho en el nodo del proyecto en el Explorador de soluciones y seleccione Agregar un nuevo elemento. Seleccione la opción DataSet de la lista de plantillas y asígnele el nombre Northwind.xsd.

Choose to Add a New DataSet to Your Project

Figura 4: Elegir agregar un nuevo DataSet a su proyecto (haga clic para ver la imagen a tamaño completo)

Tras hacer clic en Añadir, cuando se le pida que agregue el DataSet a la carpeta App_Code, elija Sí. A continuación, aparecerá el Diseñador para el DataSet tipado y se iniciará el Asistente de configuración de TableAdapter, que le permitirá agregar su primer TableAdapter al DataSet tipado.

Un DataSet tipado sirve como colección de datos fuertemente tipados; se compone de instancias DataTable fuertemente tipadas, cada una de las cuales se compone a su vez de instancias DataRow fuertemente tipadas. Crearemos un DataTable fuertemente tipado para cada una de las tablas de base de datos subyacentes con las que necesitemos trabajar en esta serie de tutoriales. Empecemos creando una DataTable para la tabla Products.

Tenga en cuenta que las DataTables fuertemente tipadas no incluyen ninguna información sobre cómo acceder a los datos desde su tabla de base de datos subyacente. Para recuperar los datos con los que rellenar la DataTable, utilizamos una clase TableAdapter, que funciona como nuestra capa de acceso a los datos. Para nuestra DataTable Products, TableAdapter contendrá los métodos GetProducts(), GetProductByCategoryID(categoryID), etc. que invocaremos desde la capa de presentación. El rol de DataTable es actuar como los objetos fuertemente tipados usados para pasar datos entre las capas.

El Asistente para configuración de TableAdapter comienza si le pide que seleccione la base de datos con la que trabajar. La lista desplegable muestra esas bases de datos en el Explorador de servidores. Si no ha agregado la base de datos Northwind al Explorador de servidores, puede hacer clic en el botón Nueva conexión en este momento para hacerlo.

Choose the Northwind Database from the Drop-Down List

Figura 5: Elegir la base de datos Northwind de la lista desplegable (haga clic para ver la imagen a tamaño completo)

Tras seleccionar la base de datos y hacer clic en Siguiente, se le preguntará si desea guardar la cadena de conexión en el archivo Web.config. Al guardar el cadena de conexión evitará que se codifique de forma rígida en las clases TableAdapter, lo que simplifica las cosas si la información de cadena de conexión cambia en el futuro. Si opta por guardar la cadena de conexión en el archivo de configuración, se coloca en la sección <connectionStrings>, que puede cifrarse opcionalmente para mejorar la seguridad o modificarse posteriormente a través de la nueva página de propiedades ASP.NET 2.0 dentro de la herramienta de administración GUI de IIS, más idónea para administradores.

Save the Connection String to Web.config

Figura 6: Guardar la cadena de conexión en Web.config (haga clic para ver la imagen a tamaño completo)

A continuación, es necesario definir el esquema para la primera DataTable fuertemente tipada y proporcionar el primer método para que TableAdapter lo use al rellenar el DataSet fuertemente tipado. Estos dos pasos se realizan simultáneamente mediante la creación de una consulta que devuelva las columnas de la tabla que queremos reflejar en nuestra DataTable. Al final del asistente, asignaremos un nombre de método a esta consulta. Una vez que se haya realizado, este método se puede invocar desde nuestra capa de presentación. El método ejecutará la consulta definida y rellenará una DataTable fuertemente tipada.

Para empezar a definir la consulta SQL, primero debemos indicar cómo queremos que TableAdapter emita la consulta. Podemos usar una instrucción SQL ad hoc, crear un nuevo procedimiento almacenado o usar un procedimiento almacenado existente. Para estos tutoriales, usaremos instrucciones SQL ad hoc.

Query the Data Using an Ad-Hoc SQL Statement

Figura 7: Consultar los datos mediante una instrucción SQL ad hoc (haga clic para ver la imagen a tamaño completo)

En este momento, podemos escribir manualmente en la consulta SQL. Al crear el primer método en TableAdapter, normalmente desea que la consulta devuelva las columnas que deben expresarse en la tabla de datos correspondiente. Podemos conseguirlo creando una consulta que devuelva todas las columnas y todas las filas de la tabla Products:

Enter the SQL Query Into the Textbox

Figura 8: Introducir la consulta SQL en el cuadro de texto (haga clic para ver la imagen a tamaño completo)

Como alternativa, use el Generador de consultas y construya gráficamente la consulta, como se muestra en la figura 9.

Create the Query Graphically, through the Query Editor

Figura 9: Crear la consulta gráficamente, a través del editor de consultas (haga clic para ver la imagen a tamaño completo)

Después de crear la consulta, pero antes de pasar a la pantalla siguiente, pulse el botón Opciones avanzadas. En los proyectos de sitios web, "Generar instrucciones Insert, Update y Delete" es la única opción avanzada seleccionada de forma predeterminada; si ejecuta este asistente desde una biblioteca de clases o un proyecto Windows, también se seleccionará la opción " Usar simultaneidad optimista". Deje la opción "Usar simultaneidad optimista" desactivada por ahora. Examinaremos la simultaneidad optimista en tutoriales futuros.

Select Only the Generate Insert, Update, and Delete statements Option

Figura 10: Seleccionar solo la opción de generar instrucciones de inserción, actualización y eliminación (haga clic para ver la imagen a tamaño completo)

Después de comprobar las opciones avanzadas, haga clic en Siguiente para continuar con la pantalla final. Aquí se le pide que seleccione los métodos que se van a agregar a TableAdapter. Hay dos patrones para rellenar los datos:

  • Rellenar una DataTable con este enfoque, se crea un método que toma DataTable como parámetro y lo rellena en función de los resultados de la consulta. La clase ADO.NET DataAdapter, por ejemplo, implementa este patrón con su método Fill().
  • Devolver un DataTable con este enfoque el método crea y rellena el DataTable por usted y lo devuelve como valor de retorno del método.

Puede hacer que TableAdapter implemente uno o ambos patrones. También puede cambiar el nombre de los métodos proporcionados aquí. Vamos a dejar activadas ambas casillas, aunque solo usaremos el último patrón en estos tutoriales. Además, cambiemos el nombre del método bastante genérico GetData a GetProducts.

Si está activada, la casilla final, "GenerateDBDirectMethods", crea métodos Insert(), Update() y Delete() para TableAdapter. Si deja esta opción sin marcar, todas las actualizaciones tendrán que realizarse a través del único método Update() del TableAdapter, que recibe el DataSet tipado, un DataTable, una única DataRow o una matriz de DataRows. (Si ha desmarcado la opción "Generar instrucciones de inserción, actualización y eliminación" de las propiedades avanzadas de la figura 9, la configuración de esta casilla no tendrá ningún efecto). Vamos a dejar esta casilla activada.

Change the Method Name from GetData to GetProducts

Figura 11: Cambiar el nombre del método de GetData a GetProducts (haga clic para ver la imagen a tamaño completo)

Para finalizar el asistente, haga clic en Instalar. Una vez que el asistente se cierra, se devuelve al Diseñador de DataSet que muestra la tabla de datos que acabamos de crear. Puede ver la lista de columnas en DataTable Products (ProductID, ProductName, etc.), así como los métodos de ProductsTableAdapter (Fill() y GetProducts()).

The Products DataTable and ProductsTableAdapter have been Added to the Typed DataSet

Figura 12: DataTable Products y ProductsTableAdapter se han agregado al conjunto de datos con tipo (haga clic para ver la imagen a tamaño completo)

En este punto, tenemos un DataSet con tipo con una única DataTable (Northwind.Products) y una clase DataAdapter fuertemente tipada (NorthwindTableAdapters.ProductsTableAdapter) con un método GetProducts(). Estos objetos se pueden usar para tener acceso a una lista de todos los productos desde código como:

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim products as Northwind.ProductsDataTable
products = productsAdapter.GetProducts()
For Each productRow As Northwind.ProductsRow In products
    Response.Write("Product: " & productRow.ProductName & "<br />")
Next

Este código no requirió que escribiéramos ni un bit de código específico de acceso a datos. No tuvimos que crear instancias de ninguna clase ADO.NET, no tuvimos que hacer referencia a ninguna cadena de conexión, consulta SQL o procedimiento almacenado. En su lugar, el TableAdapter nos proporciona el código de acceso a datos de bajo nivel.

Cada objeto usado en este ejemplo también está fuertemente tipado, lo que permite a Visual Studio proporcionar IntelliSense y comprobación de tipos en tiempo de compilación. Y lo mejor de todo es que las DataTables devueltas por el TableAdapter pueden vincularse a controles web de datos ASP.NET, como el GridView, el DetailsView, el DropDownList, el CheckBoxList y varios otros. El siguiente ejemplo ilustra la vinculación de la DataTable devuelta por el método GetProducts() a un GridView en apenas tres líneas de código dentro del controlador de eventos Page_Load.

AllProducts.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="AllProducts.aspx.vb"
    Inherits="AllProducts" %>
<!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>View All Products in a GridView</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            All Products</h1>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

AllProducts.aspx.vb

Imports NorthwindTableAdapters
Partial Class AllProducts
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
        Dim productsAdapter As New ProductsTableAdapter
        GridView1.DataSource = productsAdapter.GetProducts()
        GridView1.DataBind()
    End Sub
End Class

The List of Products is Displayed in a GridView

Figura 13: La lista de productos se muestra en un GridView (haga clic para ver la imagen a tamaño completo)

Aunque este ejemplo ha requerido que escribamos tres líneas de código en el controlador de eventos Page_Load de nuestra página ASP.NET, en futuros tutoriales examinaremos cómo utilizar el ObjectDataSource para recuperar de forma declarativa los datos de la DAL. Con ObjectDataSource no tendremos que escribir ningún código y también obtenemos compatibilidad de paginación y ordenación.

Paso 3: Agregar métodos con parámetros a la capa de acceso a datos

En este momento nuestra clase ProductsTableAdapter tiene un método, GetProducts(), que devuelve todos los productos de la base de datos. Aunque poder trabajar con todos los productos es definitivamente útil, hay ocasiones en las que queremos recuperar información sobre un producto específico o todos los productos que pertenecen a una categoría determinada. Para agregar esta funcionalidad a nuestra capa de acceso a datos, podemos agregar métodos parametrizados a TableAdapter.

Vamos a agregar el método GetProductsByCategoryID(categoryID). Para agregar un nuevo método a la DAL, vuelva al Diseñador de DataSet, haga clic con el botón derecho del ratón en la sección ProductsTableAdapter y seleccione Agregar consulta.

Right-Click on the TableAdapter and Choose Add Query

Figura 14: Hacer clic con el botón derecho en el TableAdapter y elegir Agregar consulta

Primero se nos pregunta si queremos acceder a la base de datos mediante una instrucción SQL ad hoc o un procedimiento almacenado nuevo o ya existente. Vamos a elegir usar una instrucción SQL ad hoc de nuevo. A continuación, se nos pregunta qué tipo de consulta SQL nos gustaría usar. Como queremos devolver todos los productos que pertenecen a una categoría especificada, queremos escribir una instrucción SELECT que devuelva filas.

Choose to Create a SELECT Statement Which Returns Rows

Figura 15: Elegir crear una instrucción SELECT que devuelve filas (haga clic para ver la imagen a tamaño completo)

El siguiente paso consiste en definir la consulta SQL que se usa para acceder a los datos. Como queremos devolver solo los productos que pertenecen a una categoría determinada, utilizo la misma instrucción SELECT de GetProducts(), pero añadiéndole la siguiente cláusula WHERE: WHERE CategoryID = @CategoryID. El parámetro @CategoryID indica al asistente de TableAdapter que el método que estamos creando requerirá un parámetro de entrada del tipo correspondiente (es decir, un entero anulable).

Enter a Query to Only Return Products in a Specified Category

Figura 16: Introducir una consulta para devolver solo los productos de una categoría especificada (haga clic para ver la imagen a tamaño completo)

En el paso final, podemos elegir qué patrones de acceso a datos usar, así como personalizar los nombres de los métodos generados. Para el patrón Fill, vamos a cambiar el nombre a FillByCategoryID y para devolver un patrón de retorno de DataTable (los métodos GetX), vamos a usar GetProductsByCategoryID.

Choose the Names for the TableAdapter Methods

Figura 17: Elegir los nombres de los métodos TableAdapter (haga clic para ver la imagen a tamaño completo)

Una vez completado el asistente, el Diseñador de DataSet incluye los nuevos métodos TableAdapter.

The Products Can Now be Queried by Category

Figura 18: Ahora se pueden consultar los productos por categoría

Dedique un momento a agregar un método GetProductByProductID(productID) mediante la misma técnica.

Estas consultas parametrizadas se pueden probar directamente desde el Diseñador de DataSet. Haga clic con el botón derecho en el método en TableAdapter y elija Vista previa de datos. A continuación, escriba los valores que se van a usar para los parámetros y haga clic en Vista previa.

Those Products Belonging to the Beverages Category are Shown

Figura 19: Se muestran los productos pertenecientes a la categoría de bebidas (haga clic para ver la imagen a tamaño completo)

Con el método GetProductsByCategoryID(categoryID) de nuestra DAL, ahora podemos crear una página ASP.NET que muestre solo los productos de una categoría especificada. El siguiente ejemplo muestra todos los productos que se encuentran en la categoría Bebidas, que tienen un CategoryID de 1.

Beverages.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Beverages.aspx.vb"
    Inherits="Beverages" %>
<!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>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Beverages</h1>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             CssClass="DataWebControlStyle">
               <HeaderStyle CssClass="HeaderStyle" />
               <AlternatingRowStyle CssClass="AlternatingRowStyle" />
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

Beverages.aspx.vb

Imports NorthwindTableAdapters
Partial Class Beverages
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
        Dim productsAdapter As New ProductsTableAdapter
        GridView1.DataSource =
         productsAdapter.GetProductsByCategoryID(1)
        GridView1.DataBind()
    End Sub
End Class

Those Products in the Beverages Category are Displayed

Figura 20: Se muestran los productos de la categoría de bebidas (haga clic para ver la imagen a tamaño completo)

Paso 4: Insertar, actualizar y eliminar datos

Normalmente se usan dos patrones para insertar, actualizar y eliminar datos. El primer patrón, que llamaré patrón directo de la base de datos, implica la creación de métodos que, cuando se invocan, emiten un comando INSERT, UPDATE o DELETE a la base de datos que opera sobre un único registro de la base de datos. A estos métodos se les suele pasar una serie de valores escalares (enteros, cadenas, booleanos, DateTimes, etc.) que corresponden a los valores a insertar, actualizar o eliminar. Por ejemplo, con este patrón para la tabla Products, el método de borrado tomaría un parámetro entero, indicando ProductID del registro a eliminar, mientras que el método de inserción tomaría una cadena para ProductName, un decimal para UnitPrice, un entero para UnitsOnStock, y así sucesivamente.

Each Insert, Update, and Delete Request is Sent to the Database Immediately

Figura 21: Cada solicitud de inserción, actualización y eliminación se envía a la base de datos inmediatamente (haga clic para ver la imagen a tamaño completo)

El otro patrón, al que me referiré como patrón de actualización por lotes, consiste en actualizar todo un DataSet, DataTable o colección de DataRows en una llamada a un método. Con este patrón, un desarrollador elimina, inserta y modifica DataRows en una DataTable y, a continuación, pasa esos DataRows o DataTable a un método de actualización. A continuación, este método enumera los DataRows pasados, determina si se han modificado, añadido o eliminado (a través del valor de la propiedad RowState del DataRow) y emite la solicitud a la base de datos adecuada para cada registro.

All Changes are Synchronized with the Database When the Update Method is Invoked

Figura 22: Todos los cambios se sincronizan con la base de datos cuando se invoca el método de actualización (haga clic para ver la imagen a tamaño completo)

TableAdapter usa el patrón de actualización por lotes de forma predeterminada, pero también admite el patrón directo de base de datos. Dado que seleccionamos la opción "Generar instrucciones Insert, Update y Delete" de las Propiedades avanzadas al crear nuestro TableAdapter, ProductsTableAdapter contiene un método Update(), que implementa el patrón de actualización por lotes. En concreto, el TableAdapter contiene un método Update() al que se le puede pasar el DataSet tipado, una DataTable fuertemente tipada o una o varias DataRows. Si dejó marcada la casilla "GenerateDBDirectMethods" al crear por primera vez el TableAdapter, el patrón directo de base de datos también se implementará a través de los métodos Insert(), Update() y Delete().

Ambos patrones de modificación de datos usan las propiedades InsertCommand, UpdateCommand y DeleteCommand de TableAdapter para emitir sus comandos INSERT, UPDATE y DELETE a la base de datos. Puede inspeccionar y modificar las propiedades InsertCommand, UpdateCommand y DeleteCommand haciendo clic en el TableAdapter en DataSet Designer y yendo después a la ventana Propiedades. (Asegúrese de que ha seleccionado el TableAdapter y de que el objeto ProductsTableAdapter es el que está seleccionado en la lista desplegable de la ventana Propiedades).

The TableAdapter has InsertCommand, UpdateCommand, and DeleteCommand Properties

Figura 23: TableAdapter tiene InsertCommandpropiedades, UpdateCommandy DeleteCommand (haga clic para ver la imagen a tamaño completo)

Para examinar o modificar cualquiera de estas propiedades de los comandos de la base de datos, haga clic en la subpropiedad CommandText, con lo que aparecerá el Generador de consultas.

Configure the INSERT, UPDATE, and DELETE Statements in the Query Builder

Figura 24: Configurar las instrucciones INSERT, UPDATE y DELETE en el Generador de consultas (haga clic para ver la imagen a tamaño completo)

En el ejemplo de código siguiente se muestra cómo usar el patrón de actualización por lotes para duplicar el precio de todos los productos que no están descontinuados y que tienen 25 unidades en existencias o menos:

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim products As Northwind.ProductsDataTable = productsAdapter.GetProducts()
For Each product As Northwind.ProductsRow In products
   If Not product.Discontinued AndAlso product.UnitsInStock <= 25 Then
      product.UnitPrice *= 2
   End if
Next
productsAdapter.Update(products)

En el código siguiente se muestra cómo usar el patrón directo de base de datos para eliminar mediante programación un producto determinado, actualizar uno y, a continuación, agregar uno nuevo:

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
productsAdapter.Delete(3)
productsAdapter.Update( _
    "Chai", 1, 1, "10 boxes x 20 bags", 18.0, 39, 15, 10, false, 1)
productsAdapter.Insert( _
    "New Product", 1, 1, "12 tins per carton", 14.95, 15, 0, 10, false)

Crear métodos de inserción, actualización y eliminación personalizados

Los métodos Insert(), Update() y Delete() creados por el método directo de base de datos pueden ser un poco engorrosos, especialmente para tablas con muchas columnas. Si observamos el ejemplo de código anterior, sin la ayuda de IntelliSense no queda especialmente claro qué columna de la tabla Products corresponde a cada parámetro de entrada de los métodos Update() y Insert(). Puede haber ocasiones en las que solo queramos actualizar una o dos columnas, o queramos un método Insert() personalizado que, tal vez, devuelva el valor del campo IDENTITY (autoincremento) del registro recién insertado.

Para crear este método personalizado, vuelva al Diseñador de DataSet. Haga clic con el botón derecho en TableAdapter y elija Agregar consulta y vuelva al Asistente para TableAdapter. En la segunda pantalla, podemos indicar el tipo de consulta que se va a crear. Vamos a crear un método que agregue un nuevo producto y luego devuelva el valor del ProductID del registro recién agregado. Por lo tanto, opte por crear una consulta INSERT.

Create a Method to Add a New Row to the Products Table

Figura 25: Crear un método para agregar una nueva fila a la tabla Products (haga clic para ver la imagen a tamaño completo)

En la siguiente pantalla, aparece el elemento de InsertCommandCommandText. Aumente esta consulta añadiendo SELECT SCOPE_IDENTITY() al final de la consulta, lo que devolverá el último valor de identidad insertado en una columna IDENTITY del mismo ámbito. (Consulte la documentación técnica para obtener más información sobre SCOPE_IDENTITY() y por qué probablemente desee usar SCOPE_IDENTITY() en lugar de @@IDENTITY). Asegúrese de terminar la instrucción INSERT con un punto y coma antes de agregar la instrucción SELECT.

Augment the Query to Return the SCOPE_IDENTITY() Value

Figura 26: Aumentar la consulta para devolver el valor SCOPE_IDENTITY() (haga clic para ver la imagen a tamaño completo)

Por último, asigne al nuevo método el nombre InsertProduct.

Set the New Method Name to InsertProduct

Figura 27: Establecer el nuevo nombre del método como InsertProduct (haga clic para ver la imagen a tamaño completo)

Cuando vuelva al Diseñador de DataSet, verá que el ProductsTableAdapter contiene un nuevo método, InsertProduct. Si este nuevo método no tiene un parámetro para cada columna de la tabla Products, lo más probable es que haya olvidado terminar la instrucción INSERT con un punto y coma. Configure el método InsertProduct y asegúrese de que tiene un punto y coma delimitando las instrucciones INSERT y SELECT.

De forma predeterminada, los métodos de inserción emiten métodos que no son de consulta, lo que significa que devuelven el número de filas afectadas. Sin embargo, queremos que el método InsertProduct devuelva el valor devuelto por la consulta, no el número de filas afectadas. Para ello, ajuste la propiedad ExecuteMode del método InsertProduct a Scalar.

Change the ExecuteMode Property to Scalar

Figura 28: Cambiar la propiedad ExecuteMode a Scalar (haga clic para ver la imagen a tamaño completo)

El código siguiente muestra este nuevo método InsertProduct en acción:

Dim productsAdapter As New NorthwindTableAdapters.ProductsTableAdapter()
Dim new_productID As Integer = Convert.ToInt32(productsAdapter.InsertProduct( _
    "New Product", 1, 1, "12 tins per carton", 14.95, 10, 0, 10, false))
productsAdapter.Delete(new_productID)

Paso 5: Crear la capa de acceso a datos

Tenga en cuenta que la clase ProductsTableAdapters devuelve los valores CategoryID y SupplierID de la tabla Products, pero no incluye la columna CategoryName de la tabla Categories o la columna CompanyName de la tabla Suppliers, aunque es probable que se muestren las columnas que queremos mostrar al mostrar información del producto. Podemos aumentar el método inicial del TableAdapter, GetProducts(), para incluir los valores de las columnas CategoryName y CompanyName, lo que actualizará el DataTable fuertemente tipado para incluir también estas nuevas columnas.

Sin embargo, esto puede presentar un problema, ya que los métodos de TableAdapter para insertar, actualizar y eliminar datos se basan en este método inicial. Afortunadamente, los métodos autogenerados para insertar, actualizar y eliminar no se ven afectados por las subconsultas de la cláusula SELECT. Si tenemos cuidado de añadir nuestras consultas a Categories y Suppliers como subconsultas, en lugar de JOIN, evitaremos tener que rehacer esos métodos para modificar los datos. Haga clic con el botón derecho en el método GetProducts() en ProductsTableAdapter y elija Configurar. A continuación, ajuste la cláusula SELECT para que tenga el siguiente aspecto:

SELECT     ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,
(SELECT CategoryName FROM Categories
WHERE Categories.CategoryID = Products.CategoryID) as CategoryName,
(SELECT CompanyName FROM Suppliers
WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName
FROM         Products

Update the SELECT Statement for the GetProducts() Method

Figura 29: Actualizar la instrucción SELECT para el método GetProducts() ( haga clic para ver la imagen a tamaño completo)

Después de actualizar el método GetProducts() para usar esta nueva consulta, DataTable incluirá dos columnas nuevas: CategoryName y SupplierName.

The Products DataTable has Two New Columns

Figura 30: DataTable Products tiene dos nuevas columnas

Dedique un momento a actualizar también la cláusula SELECT en el método GetProductsByCategoryID(categoryID).

Si actualiza el GetProducts()SELECT utilizando la sintaxis JOIN, el Diseñador de DataSet no podrá autogenerar los métodos para insertar, actualizar y eliminar datos de la base de datos utilizando el patrón directo de base de datos. En su lugar, tendrá que crearlos manualmente como hicimos con el método InsertProduct anteriormente en este tutorial. Además, tendrá que proporcionar manualmente los valores de las propiedades InsertCommand, UpdateCommand y DeleteCommand si desea utilizar el patrón de actualización por lotes.

Agregar los TableAdapters restantes

Hasta ahora, solo hemos visto cómo trabajar con un único TableAdapter para una única tabla de la base de datos. Sin embargo, la base de datos Northwind contiene varias tablas relacionadas con las que tendremos que trabajar en nuestra aplicación web. Un DataSet tipado puede contener varias DataTables relacionadas. Por lo tanto, para completar nuestra DAL, es necesario agregar DataTables para las otras tablas que usaremos en estos tutoriales. Para agregar un nuevo TableAdapter a un DataSet tipado, abra el Diseñador de DataSet, haga clic con el botón derecho en el Diseñador y elija Agregar/TableAdapter. Esto creará una nueva DataTable y TableAdapter y le guiará por el asistente que hemos examinado anteriormente en este tutorial.

Dedique unos minutos a crear los siguientes TableAdapters y métodos mediante las siguientes consultas. Tenga en cuenta que las consultas de ProductsTableAdapter incluyen las subconsultas para obtener los nombres de proveedor y categoría de cada producto. Además, si ha seguido los pasos, ya ha agregado los métodos GetProducts() y GetProductsByCategoryID(categoryID) la clase ProductsTableAdapter.

  • ProductsTableAdapter

    • GetProducts:

      SELECT     ProductID, ProductName, SupplierID, 
      CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, 
      UnitsOnOrder, ReorderLevel, Discontinued, 
      (SELECT CategoryName FROM Categories WHERE
      Categories.CategoryID = Products.CategoryID) as 
      CategoryName, (SELECT CompanyName FROM Suppliers
      WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      
    • GetProductsByCategoryID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName,
      (SELECT CompanyName FROM Suppliers WHERE
      Suppliers.SupplierID = Products.SupplierID)
      as SupplierName
      FROM         Products
      WHERE      CategoryID = @CategoryID
      
    • GetProductsBySupplierID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE 
      Suppliers.SupplierID = Products.SupplierID) as SupplierName
      FROM         Products
      WHERE SupplierID = @SupplierID
      
    • GetProductByProductID:

      SELECT     ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued, (SELECT CategoryName 
      FROM Categories WHERE Categories.CategoryID = 
      Products.CategoryID) as CategoryName, 
      (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) 
      as SupplierName
      FROM         Products
      WHERE ProductID = @ProductID
      
  • CategoriesTableAdapter

    • GetCategories:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      
    • GetCategoryByCategoryID:

      SELECT     CategoryID, CategoryName, Description
      FROM         Categories
      WHERE CategoryID = @CategoryID
      
  • SuppliersTableAdapter

    • GetSuppliers:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      
    • GetSuppliersByCountry:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE Country = @Country
      
    • GetSupplierBySupplierID:

      SELECT     SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM         Suppliers
      WHERE SupplierID = @SupplierID
      
  • EmployeesTableAdapter

    • GetEmployees:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      
    • GetEmployeesByManager:

      SELECT     EmployeeID, LastName, FirstName, Title, 
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE ReportsTo = @ManagerID
      
    • GetEmployeeByEmployeeID:

      SELECT     EmployeeID, LastName, FirstName, Title,
      HireDate, ReportsTo, Country
      FROM         Employees
      WHERE EmployeeID = @EmployeeID
      

The DataSet Designer After the Four TableAdapters Have Been Added

Figura 31: El diseñador DataSet después de agregar los cuatro TableAdapters (haga clic para ver la imagen a tamaño completo)

Agregar código personalizado a la DAL

Los TableAdapters y DataTables agregados al DataSet tipado se expresan como un archivo de definición de esquema XML (Northwind.xsd). Puede ver esta información del esquema haciendo clic con el botón derecho en el archivo Northwind.xsd en el Explorador de soluciones y seleccionando Ver código.

The XML Schema Definition (XSD) File for the Northwinds Typed DataSet

Figura 32: El archivo de definición de esquema XML (XSD) para el DataSet tipado Northwinds (haga clic para ver la imagen a tamaño completo)

Esta información de esquema se traduce en código de C# o Visual Basic en tiempo de diseño cuando se compila o en tiempo de ejecución (si es necesario), en cuyo momento puede recorrerlo con el depurador. Para ver este código generado automáticamente, vaya a la vista de clases y explore en profundidad las clases TableAdapter o DataSet tipado. Si no ve la vista de clases en la pantalla, vaya al menú Ver y selecciónelo desde allí o presione Ctrl+Mayús+C. En la Vista de clases puede ver las propiedades, los métodos y los eventos de las clases DataSet tipado y TableAdapter. Para ver el código de un método determinado, haga doble clic en el nombre del método en la Vista de clases o haga clic con el botón derecho en él y elija Ir a definición.

Inspect the Auto-Generated Code by Selecting Go To Definition from the Class View

Figura 33: Inspección del código generado automáticamente seleccionando Ir a definición en la vista de clases

Aunque el código generado automáticamente puede ser un gran ahorro de tiempo, el código suele ser muy genérico y debe personalizarse para satisfacer las necesidades únicas de una aplicación. Sin embargo, el riesgo de extender el código generado automáticamente es que la herramienta que generó el código podría decidir que es el momento de "regenerar" y sobrescribir las personalizaciones. Con el nuevo concepto de clase parcial de .NET 2.0, es fácil dividir una clase entre varios archivos. Esto nos permite agregar nuestros propios métodos, propiedades y eventos a las clases generadas automáticamente sin tener que preocuparse de que Visual Studio sobrescriba nuestras personalizaciones.

Para demostrar cómo personalizar la DAL, agreguemos un método GetProducts() a la clase SuppliersRow. La clase SuppliersRow representa un único registro en la tabla Suppliers; cada proveedor puede tener de cero a muchos productos, por lo que GetProducts() devolverá aquellos productos del proveedor especificado. Para ello, cree un nuevo archivo de clase en la App_Code carpeta denominada SuppliersRow.vb y agregue el código siguiente:

Imports NorthwindTableAdapters
Partial Public Class Northwind
    Partial Public Class SuppliersRow
        Public Function GetProducts() As Northwind.ProductsDataTable
            Dim productsAdapter As New ProductsTableAdapter
            Return productsAdapter.GetProductsBySupplierID(Me.SupplierID)
        End Function
    End Class
End Class

Esta clase parcial indica al compilador que cuando compile la clase Northwind.SuppliersRow incluya el método GetProducts() que acabamos de definir. Si compila el proyecto y luego vuelve a la vista de clases, verá que GetProducts() aparece ahora como un método de Northwind.SuppliersRow.

The GetProducts() Method is Now Part of the Northwind.SuppliersRow Class

Figura 34: El método GetProducts() ahora forma parte de la clase Northwind.SuppliersRow

El método GetProducts() puede usarse ahora para enumerar el conjunto de productos de un proveedor concreto, como muestra el código siguiente:

Dim suppliersAdapter As New NorthwindTableAdapters.SuppliersTableAdapter()
Dim suppliers As Northwind.SuppliersDataTable = suppliersAdapter.GetSuppliers()
For Each supplier As Northwind.SuppliersRow In suppliers
    Response.Write("Supplier: " & supplier.CompanyName)
    Response.Write("<ul>")
    Dim products As Northwind.ProductsDataTable = supplier.GetProducts()
    For Each product As Northwind.ProductsRow In products
        Response.Write("<li>" & product.ProductName & "</li>")
    Next
    Response.Write("</ul><p> </p>")
Next

Estos datos también pueden mostrarse en cualquiera de los controles web de datos de ASP.NET. La siguiente página utiliza un control GridView con dos campos:

  • Un BoundField que muestre el nombre de cada proveedor, y
  • Un TemplateField que contiene un control BulletedList vinculado a los resultados devueltos por el método GetProducts() para cada proveedor.

Examinaremos cómo mostrar estos informes maestros y de detalles en tutoriales futuros. Por ahora, este ejemplo está diseñado para ilustrar el uso del método personalizado agregado a la clase Northwind.SuppliersRow.

SuppliersAndProducts.aspx

<%@ Page Language="VB" CodeFile="SuppliersAndProducts.aspx.vb"
    AutoEventWireup="true" Inherits="SuppliersAndProducts" %>
<!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>Untitled Page</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>
            Suppliers and Their Products</h1>
        <p>
            <asp:GridView ID="GridView1" runat="server"
             AutoGenerateColumns="False"
             CssClass="DataWebControlStyle">
                <HeaderStyle CssClass="HeaderStyle" />
                <AlternatingRowStyle CssClass="AlternatingRowStyle" />
                <Columns>
                    <asp:BoundField DataField="CompanyName"
                      HeaderText="Supplier" />
                    <asp:TemplateField HeaderText="Products">
                        <ItemTemplate>
                            <asp:BulletedList ID="BulletedList1"
                             runat="server" DataSource="<%# CType(CType(Container.DataItem, System.Data.DataRowView).Row, Northwind.SuppliersRow).GetProducts() %>"
                                 DataTextField="ProductName">
                            </asp:BulletedList>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
             </p>
    </div>
    </form>
</body>
</html>

SuppliersAndProducts.aspx.vb

Imports NorthwindTableAdapters
Partial Class SuppliersAndProducts
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
        Dim suppliersAdapter As New SuppliersTableAdapter
        GridView1.DataSource = suppliersAdapter.GetSuppliers()
        GridView1.DataBind()
    End Sub
End Class

The Supplier's Company Name is Listed in the Left Column, Their Products in the Right

Figura 35: El nombre de la empresa del proveedor aparece en la columna de la izquierda, sus productos en la de la derecha (haga clic para ver la imagen a tamaño completo)

Resumen

Cuando construya una aplicación web, crear la DAL debería ser uno de sus primeros pasos, antes de empezar a crear su capa de presentación. Con Visual Studio, crear una DAL basada en DataSets tipados es una tarea que puede realizarse en 10-15 minutos sin escribir una línea de código. Los tutoriales que se realicen en el futuro se basarán en esta DAL. En el siguiente tutorial definiremos una serie de reglas de negocio y veremos cómo implementarlas en una capa de lógica de negocios independiente.

¡Feliz programación!

Lecturas adicionales

Para obtener más información sobre los temas tratados en este tutorial, consulte los siguientes recursos:

Aprendizaje en vídeo sobre temas incluidos en este tutorial

Acerca del autor

Scott Mitchell, autor de siete libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha estado trabajando con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, entrenador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Puede ponerse en contacto con él a través de mitchell@4GuysFromRolla.com. o a través de su blog, que se puede encontrar en http://ScottOnWriting.NET.

Agradecimientos especiales a

Muchos revisores han evaluado esta serie de tutoriales. Los clientes principales de este tutorial fueron Ron Green, Hilton Giesenow, Dennis Patterson, Liz Shulok, Abel Gomez y Carlos Santos. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.