Usar procedimientos almacenados existentes para los TableAdapters del conjunto de datos con tipo (C#)

por Scott Mitchell

Descargar PDF

En el tutorial anterior hemos aprendido a usar el Asistente para TableAdapter para generar nuevos procedimientos almacenados. En este tutorial, veremos cómo el mismo Asistente para TableAdapter puede trabajar con procedimientos almacenados existentes. También aprenderemos a agregar manualmente nuevos procedimientos almacenados a nuestra base de datos.

Introducción

En el tutorial anterior vimos cómo se podía configurar TableAdapters del Conjunto de datos con tipo para usar procedimientos almacenados para acceder a datos en lugar de instrucciones SQL ad hoc. En concreto, hemos examinado cómo hacer que el asistente para TableAdapter cree automáticamente estos procedimientos almacenados. Al migrar una aplicación heredada a ASP.NET 2.0 o al compilar un sitio web de ASP.NET 2.0 en torno a un modelo de datos existente, es probable que la base de datos ya contenga los procedimientos almacenados que necesitamos. Como alternativa, puede que prefiera crear los procedimientos almacenados manualmente o a través de alguna herramienta distinta del Asistente para TableAdapter que genere automáticamente los procedimientos almacenados.

En este tutorial veremos cómo configurar TableAdapter para usar procedimientos almacenados existentes. Dado que la base de datos de Northwind solo tiene un pequeño conjunto de procedimientos almacenados integrados, también veremos los pasos necesarios para agregar manualmente nuevos procedimientos almacenados a la base de datos a través del entorno de Visual Studio. ¡Comencemos!

Nota:

En el tutorial Ajuste de las modificaciones de la base de datos dentro de una transacción, agregamos métodos a TableAdapter para admitir transacciones (BeginTransaction, CommitTransaction, etc.). Como alternativa, las transacciones se pueden administrar completamente dentro de un procedimiento almacenado, lo que no requiere modificaciones en el código de capa de acceso a datos. En este tutorial exploraremos los comandos de T-SQL que se usan para ejecutar instrucciones de un procedimiento almacenado dentro del ámbito de una transacción.

Paso 1: agregar procedimientos almacenados a la base de datos de Northwind

Visual Studio facilita la adición de nuevos procedimientos almacenados a una base de datos. Vamos a agregar un nuevo procedimiento almacenado a la base de datos de Northwind que devuelve todas las columnas de la tabla Products para aquellas que tienen un valor CategoryID determinado. En la ventana Explorador de servidores, expanda la base de datos de Northwind para que se muestren sus carpetas (Diagramas de base de datos, Tablas, Vistas, etc.). Como vimos en el tutorial anterior, la carpeta Procedimientos almacenados contiene los procedimientos almacenados existentes de la base de datos. Para agregar un nuevo procedimiento almacenado, simplemente haga clic con el botón derecho en la carpeta Procedimientos almacenados y elija la opción Agregar nuevo procedimiento almacenado en el menú contextual.

Right-Click the Stored Procedures Folder and Add a New Stored Procedure

Figura 1: haga clic con el botón derecho en la carpeta Procedimientos almacenados y agregue un nuevo procedimiento almacenado (Haga clic para ver la imagen de tamaño completo)

Como se muestra en la Figura 1, al seleccionar la opción Agregar nuevo procedimiento almacenado se abre una ventana de script en Visual Studio con el esquema del script SQL necesario para crear el procedimiento almacenado. Nuestro trabajo consiste en desarrollar este script y ejecutarlo, momento en el que el procedimiento almacenado se añadirá a la base de datos.

Escriba el siguiente script:

CREATE PROCEDURE dbo.Products_SelectByCategoryID 
(
    @CategoryID int
)
AS
SELECT ProductID, ProductName, SupplierID, CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued
FROM Products
WHERE CategoryID = @CategoryID

Este script, cuando se ejecute, agregará un nuevo procedimiento almacenado a la base de datos de Northwind denominada Products_SelectByCategoryID. Este procedimiento almacenado acepta un único parámetro de entrada (@CategoryID, de tipo int) y devuelve todos los campos de esos productos con un valor de CategoryID coincidente.

Para ejecutar este script de CREATE PROCEDURE y agregar el procedimiento almacenado a la base de datos, haga clic en el icono Guardar de la barra de herramientas o presione Ctrl+S. Después de hacerlo, la carpeta Procedimientos almacenados se actualiza, mostrando el procedimiento almacenado recién creado. Además, el script de la ventana cambiará la sutileza de CREATE PROCEDURE dbo.Products_SelectProductByCategoryID a ALTER PROCEDUREdbo.Products_SelectProductByCategoryID. CREATE PROCEDURE agrega un nuevo procedimiento almacenado a la base de datos, mientras que ALTER PROCEDURE actualiza uno existente. Dado que el inicio del script ha cambiado a ALTER PROCEDURE, al cambiar los parámetros de entrada de procedimientos almacenados o instrucciones SQL y hacer clic en el icono Guardar actualizará el procedimiento almacenado con estos cambios.

En la Figura 2 se muestra Visual Studio después de guardar el procedimiento almacenado Products_SelectByCategoryID.

The Stored Procedure Products_SelectByCategoryID Has Been Added to the Database

Figura 2: se ha agregado el procedimiento almacenado Products_SelectByCategoryID a la base de datos (Haga clic para ver la imagen de tamaño completo)

Paso 2: Configurar TableAdapter para usar un procedimiento almacenado existente

Ahora que el procedimiento almacenado Products_SelectByCategoryID se ha agregado a la base de datos, podemos configurar nuestra capa de acceso a datos para usar este procedimiento almacenado cuando se invoca uno de sus métodos. En concreto, agregaremos un método GetProductsByCategoryID(categoryID) al ProductsTableAdapter en el Conjunto de datos con tipo NorthwindWithSprocs que llama al procedimiento almacenado Products_SelectByCategoryID que acabamos de crear.

Para empezar, abra el Conjunto de datos NorthwindWithSprocs. Haga clic con el botón derecho en ProductsTableAdapter y elija Agregar consulta para iniciar el Asistente para configuración de consultas de TableAdapter. En el tutorial anterior optamos por que TableAdapter creara un nuevo procedimiento almacenado para nosotros. Sin embargo, en este tutorial queremos conectar el nuevo método de TableAdapter al procedimiento almacenado existente Products_SelectByCategoryID. Por lo tanto, elija la opción Usar procedimiento almacenado existente en el primer paso del asistente y, a continuación, haga clic en Siguiente.

Choose the Use existing stored procedure Option

Figura 3: elija la opción Usar procedimiento almacenado existente (Haga clic para ver la imagen de tamaño completo)

En la pantalla siguiente se proporciona una lista desplegable rellenada con los procedimientos almacenados de la base de datos. Al seleccionar un procedimiento almacenado se enumeran sus parámetros de entrada a la izquierda y los campos de datos devueltos (si los hay) de la derecha. Elija el procedimiento almacenado Products_SelectByCategoryID de la lista y haga clic en Siguiente.

Pick the Products_SelectByCategoryID Stored Procedure

Figura 4: Seleccionar el procedimiento almacenado Products_SelectByCategoryID (Haga clic para ver la imagen de tamaño completo)

La siguiente pantalla nos pregunta qué tipo de datos devuelve el procedimiento almacenado y nuestra respuesta determina aquí el tipo devuelto por el método TableAdapter. Por ejemplo, si indicamos que se devuelven datos tabulares, el método devolverá una instancia de ProductsDataTable rellenada con los registros devueltos por el procedimiento almacenado. En cambio, si indicamos que este procedimiento almacenado devuelve un valor único, TableAdapter devolverá un object al que se le asigna el valor en la primera columna del primer registro devuelto por el procedimiento almacenado.

Dado que el procedimiento almacenado Products_SelectByCategoryID devuelve todos los productos que pertenecen a una categoría determinada, elija la primera respuesta - Datos tabulares - y haga clic en Siguiente.

Indicate that the Stored Procedure Returns Tabular Data

Figura 5: Indicar que el procedimiento almacenado devuelve datos tabulares (Haga clic para ver la imagen de tamaño completo)

Todo lo que queda es indicar qué patrones de método usar, seguidos de los nombres de estos métodos. Deje activadas las opciones Rellenar una DataTable y Devolver una DataTable, pero cambie el nombre de los métodos a FillByCategoryID y GetProductsByCategoryID. A continuación, haga clic en Siguiente para revisar un resumen de las tareas que realizará el asistente. Si todo parece correcto, haga clic en Finalizar.

Name the Methods FillByCategoryID and GetProductsByCategoryID

Figura 6: Asigne un nombre a los métodos FillByCategoryID y GetProductsByCategoryID (Haga clic para ver la imagen de tamaño completo)

Nota:

Los métodos de TableAdapter que acabamos de crear FillByCategoryID y GetProductsByCategoryID, esperan un parámetro de entrada de tipo int. Este valor de parámetro de entrada se pasa al procedimiento almacenado a través de su parámetro @CategoryID. Si modifica los parámetros del procedimiento almacenado Products_SelectByCategory, deberá actualizar también los parámetros de estos métodos de TableAdapter. Como se explicó en el tutorial anterior, esto se puede hacer de una de estas dos maneras: agregando o quitando manualmente parámetros de la colección de parámetros o ejecutando nuevamente el Asistente para TableAdapter.

Paso 3: agregar un métodoGetProductsByCategoryID(categoryID)al BLL

Una vez completado el método DAL GetProductsByCategoryID, el siguiente paso es proporcionar acceso a este método en la capa lógica de negocios. Abra el archivo de clase ProductsBLLWithSprocs y agregue el método siguiente:

[System.ComponentModel.DataObjectMethodAttribute
    (System.ComponentModel.DataObjectMethodType.Select, false)]
public NorthwindWithSprocs.ProductsDataTable GetProductByCategoryID(int categoryID)
{
    return Adapter.GetProductsByCategoryID(categoryID);
}

Este método BLL simplemente devuelve el ProductsDataTable devuelto desde ProductsTableAdapter, por el método s GetProductsByCategoryID. El atributo DataObjectMethodAttribute proporciona metadatos utilizados por el Asistente para configurar orígenes de datos de ObjectDataSource. En concreto, este método aparecerá en la lista desplegable de la pestaña SELECT.

Paso 4: mostrar productos por categoría

Para probar el procedimiento almacenado Products_SelectByCategoryID recién agregado y los métodos DAL y BLL correspondientes, vamos a crear una página de ASP.NET que contenga un DropDownList y un GridView. DropDownList mostrará todas las categorías de la base de datos, mientras que GridView mostrará los productos que pertenecen a la categoría seleccionada.

Nota:

Hemos creado interfaces maestras y detalladas con DropDownLists en tutoriales anteriores. Para obtener una visión más detallada de la implementación de este informe maestro/detalles, consulte el tutorial Filtrado de maestros y detalles con una lista desplegable.

Abra la página ExistingSprocs.aspx en la carpeta AdvancedDAL y arrastre DropDownList desde el cuadro de herramientas al Diseñador. Establezca la propiedad ID de DropDownList en Categories y su propiedad AutoPostBack en true. A continuación, desde su etiqueta inteligente, enlace DropDownList a un nuevo ObjectDataSource denominado CategoriesDataSource. Configure ObjectDataSource para que recupere sus datos de la clase CategoriesBLL del método GetCategories. Establezca las listas desplegables en las pestañas UPDATE, INSERT y DELETE en (None).

Retrieve Data from the CategoriesBLL Class s GetCategories Method

Figura 7: Recuperar datos del método GetCategories de la clase CategoriesBLL (Haga clic para ver la imagen de tamaño completo)

Set the Drop-Down Lists in the UPDATE, INSERT, and DELETE Tabs to (None)

Figura 8: Establecer las listas desplegables en las pestañas UPDATE, INSERT y DELETE en (None) (Haga clic para ver la imagen de tamaño completo)

Después de completar el asistente ObjectDataSource, configure DropDownList para mostrar el campo de datos CategoryName y usar el campo CategoryID como Value para cada ListItem.

En este punto, el marcado declarativo DropDownList y ObjectDataSource deben ser similares a los siguientes:

<asp:DropDownList ID="Categories" runat="server" AutoPostBack="True" 
    DataSourceID="CategoriesDataSource" DataTextField="CategoryName" 
    DataValueField="CategoryID">
</asp:DropDownList>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}" 
    SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>

A continuación, arrastre GridView al Diseñador y colóquelo debajo de DropDownList. Establezca el ID de GridView en ProductsByCategory y, desde su etiqueta inteligente, vincule a un nuevo ObjectDataSource denominado ProductsByCategoryDataSource. Configure el ProductsByCategoryDataSource ObjectDataSource para usar la clase ProductsBLLWithSprocs, haciendo que recupere sus datos mediante el método GetProductsByCategoryID(categoryID). Puesto que GridView solo se usará para mostrar datos, establezca las listas desplegables en las pestañas UPDATE, INSERT y DELETE en (None) y haga clic en Siguiente.

Configure the ObjectDataSource to Use the ProductsBLLWithSprocs Class

Figura 9: configurar ObjectDataSource para usar la clase ProductsBLLWithSprocs (haga clic para ver la imagen de tamaño completo)

Retrieve Data from the GetProductsByCategoryID(categoryID) Method

Figura 10: recuperar datos del método GetProductsByCategoryID(categoryID) (haga clic para ver la imagen de tamaño completo)

El método elegido en la pestaña SELECT espera un parámetro, por lo que el paso final del asistente nos solicita el origen del parámetro. Establezca la lista desplegable Origen de parámetros en Control y elija el control Categories en la lista desplegable ControlID. Haga clic en Finalizar para completar el asistente.

Use the Categories DropDownList as the Source of the categoryID Parameter

Figura 11: use las Categories de DropDownList como origen del parámetro categoryID (haga clic para ver la imagen de tamaño completo)

Al completar el asistente de ObjectDataSource, Visual Studio agregará BoundFields y un CheckBoxField para cada uno de los campos de datos del producto. No dude en personalizar estos campos como desee.

Visite la página a través de un explorador. Al visitar la página, se selecciona la categoría Bebidas y los productos correspondientes enumerados en la cuadrícula. Al cambiar la lista desplegable a una categoría alternativa, como se muestra en la Figura 12, se produce un postback y se vuelve a cargar la cuadrícula con los productos de la categoría recién seleccionada.

The Products in the Produce Category are Displayed

Figura 12: se muestran los productos de la categoría Producir (haga clic para ver la imagen de tamaño completo)

Paso 5: encapsular instrucciones de un procedimiento almacenado dentro del ámbito de una transacción

En el tutorial Ajuste de las modificaciones de base de datos dentro de una transacción se describen técnicas para realizar una serie de instrucciones de modificación de base de datos dentro del ámbito de una transacción. Recuerde que las modificaciones realizadas bajo el ámbito de una transacción se realizan correctamente o se producen errores, lo que garantiza la atomicidad. Entre las técnicas para usar transacciones se incluyen las siguientes:

  • Uso de las clases del espacio de nombres System.Transactions,
  • Tener la capa de acceso a datos usa clases de ADO.NET como SqlTransaction y
  • Agregar los comandos de transacción de T-SQL directamente dentro del procedimiento almacenado

En el tutorial Ajuste de la base de datos dentro de un tutorial de transacciones se usaron las clases de ADO.NET en DAL. El resto de este tutorial examina cómo administrar una transacción mediante comandos T-SQL desde un procedimiento almacenado.

Los tres comandos SQL clave para iniciar, confirmar y revertir manualmente una transacción son BEGIN TRANSACTION, COMMIT TRANSACTION y ROLLBACK TRANSACTION, respectivamente. Al igual que con el enfoque de ADO.NET, cuando se usan transacciones desde dentro de un procedimiento almacenado, es necesario aplicar el siguiente patrón:

  1. Indique el inicio de una transacción.
  2. Se ejecutan las instrucciones SQL que componen la transacción.
  3. Si hay un error en cualquiera de las instrucciones del paso 2, realice la reversión de la transacción.
  4. Si todas las instrucciones del paso 2 se completan sin errores, se confirma la transacción.

Este patrón se puede implementar en la sintaxis de T-SQL mediante la plantilla siguiente:

BEGIN TRY
  BEGIN TRANSACTION -- Start the transaction
  ... Perform the SQL statements that makeup the transaction ...
  -- If we reach here, success!
  COMMIT TRANSACTION
END TRY
BEGIN CATCH 
  -- Whoops, there was an error
  ROLLBACK TRANSACTION
  -- Raise an error with the 
  -- details of the exception   
  DECLARE @ErrMsg nvarchar(4000),
          @ErrSeverity int 
  SELECT @ErrMsg = ERROR_MESSAGE(), 
         @ErrSeverity = ERROR_SEVERITY() 
 
  RAISERROR(@ErrMsg, @ErrSeverity, 1) 
END CATCH

La plantilla comienza definiendo un bloque TRY...CATCH, una construcción nueva en SQL Server 2005. Al igual que con los bloques try...catch en C#, el bloque TRY...CATCH SQL ejecuta las instrucciones en el bloque TRY. Si alguna instrucción genera un error, el control se transfiere inmediatamente al bloque CATCH.

Si no hay errores al ejecutar las instrucciones SQL que constituyen la transacción, la instrucción COMMIT TRANSACTION confirma los cambios y completa la transacción. Sin embargo, si una de las instrucciones produce un error, el ROLLBACK TRANSACTION del bloque CATCH devuelve la base de datos a su estado antes del inicio de la transacción. El procedimiento almacenado también genera un error mediante el comando RAISERROR, lo que hace que se genere una excepción SqlException en la aplicación.

Nota:

Dado que el bloque TRY...CATCH es nuevo en SQL Server 2005, la plantilla anterior no funcionará si usa versiones anteriores de Microsoft SQL Server.

Veamos un ejemplo concreto. Existe una restricción de clave externa entre las tablas Categories y Products, lo que significa que cada campo CategoryID de la tabla Products debe asignarse a un valor de CategoryID en la tabla Categories. Cualquier acción que infringiera esta restricción, como intentar eliminar una categoría que tenga productos asociados, produce una infracción de restricción de clave externa. Para comprobarlo, vuelva a consultar el ejemplo Actualización y eliminación de datos binarios existentes en la sección Trabajar con datos binarios (~/BinaryData/UpdatingAndDeleting.aspx). En esta página se muestra cada categoría del sistema junto con los botones Editar y Eliminar (vea la Figura 13), pero si intenta eliminar una categoría que tenga productos asociados (como Bebidas), se produce un error en la eliminación debido a una infracción de restricción de clave externa (vea la Figura 14).

Each Category is Displayed in a GridView with Edit and Delete Buttons

Figura 13: cada categoría se muestra en un control de GridView con botones Editar y Eliminar (haga clic para ver la imagen de tamaño completo)

You Cannot Delete a Category that has Existing Products

Figura 14: no se puede eliminar una categoría que tenga productos existentes (haga clic para ver la imagen de tamaño completo)

Sin embargo, imagine que queremos permitir que las categorías se eliminen independientemente de si tienen productos asociados. Si se elimina una categoría con productos, imagine que también queremos eliminar sus productos existentes (aunque otra opción sería simplemente establecer los valores CategoryID de sus productos en NULL). Esta funcionalidad se podría implementar mediante las reglas en cascada de la restricción de clave externa. Como alternativa, podríamos crear un procedimiento almacenado que acepte un parámetro de entrada @CategoryID y, cuando se invoque, eliminar explícitamente todos los productos asociados y, a continuación, la categoría especificada.

Nuestro primer intento en este procedimiento almacenado podría ser similar al siguiente:

CREATE PROCEDURE dbo.Categories_Delete
(
    @CategoryID int
)
AS
-- First, delete the associated products...
DELETE FROM Products
WHERE CategoryID = @CategoryID
-- Now delete the category
DELETE FROM Categories
WHERE CategoryID = @CategoryID

Aunque definitivamente eliminará los productos y categorías asociados, no lo hace bajo el ámbito de una transacción. Imagine que hay alguna otra restricción de clave externa en Categories que prohibiría la eliminación de un valor de @CategoryID determinado. El problema es que, en tal caso, todos los productos se eliminarán antes de intentar eliminar la categoría. El resultado neto es que para dicha categoría, este procedimiento almacenado eliminaría todos sus productos mientras que la categoría permanecería ya que todavía tiene registros relacionados en alguna otra tabla.

Sin embargo, si el procedimiento almacenado se encapsulaba dentro del ámbito de una transacción, las eliminaciones de la tabla Products se revertirían en el caso de una eliminación errónea en Categories. El siguiente script de procedimiento almacenado usa una transacción para garantizar la atomicidad entre las dos instrucciones DELETE:

CREATE PROCEDURE dbo.Categories_Delete
(
    @CategoryID int
)
AS
BEGIN TRY
  BEGIN TRANSACTION -- Start the transaction
  -- First, delete the associated products...
  DELETE FROM Products
  WHERE CategoryID = @CategoryID
  -- Now delete the category
  DELETE FROM Categories
  WHERE CategoryID = @CategoryID
  -- If we reach here, success!
  COMMIT TRANSACTION
END TRY
BEGIN CATCH 
  -- Whoops, there was an error
  ROLLBACK TRANSACTION
  -- Raise an error with the 
  -- details of the exception   
  DECLARE @ErrMsg nvarchar(4000),
          @ErrSeverity int 
  SELECT @ErrMsg = ERROR_MESSAGE(), 
         @ErrSeverity = ERROR_SEVERITY() 
 
  RAISERROR(@ErrMsg, @ErrSeverity, 1) 
END CATCH

Dedique un momento a agregar el procedimiento almacenado Categories_Delete a la base de datos de Northwind. Consulte el paso 1 para obtener instrucciones sobre cómo agregar procedimientos almacenados a una base de datos.

Paso 6: Actualización delCategoriesTableAdapter

Aunque hemos agregado el procedimiento almacenado Categories_Delete a la base de datos, la DAL está configurada actualmente para usar instrucciones SQL ad hoc para realizar la eliminación. Es necesario actualizar el CategoriesTableAdapter e indicarle que use el procedimiento almacenado Categories_Delete en su lugar.

Nota:

Anteriormente en este tutorial se estaba trabajando con el Conjunto de datos de NorthwindWithSprocs. Pero ese DataSet solo tiene una única entidad, ProductsDataTable y necesitamos trabajar con categorías. Por lo tanto, durante el resto de este tutorial cuando hablo sobre la capa de acceso a datos, estoy haciendo referencia al Conjunto de datos Northwind, el que creamos por primera vez en el tutorial Creación de una capa de acceso a datos.

Abra el Conjunto de datos de Northwind, seleccione CategoriesTableAdapter y vaya a la ventana Propiedades. En la ventana Propiedades se enumeran los InsertCommand, UpdateCommand, DeleteCommand y SelectCommand usados por TableAdapter, así como su información de nombre y conexión. Expanda la propiedad DeleteCommand para ver sus detalles. Como se muestra en la Figura 15, la propiedad CommandType de DeleteCommand se establece en Text, lo que indica que envíe el texto en la propiedad CommandText como una consulta SQL ad hoc.

Select the CategoriesTableAdapter in the Designer to View Its Properties in the Properties Window

Figura 15: Seleccione el CategoriesTableAdapter en el Diseñador para ver sus propiedades en la ventana Propiedades

Para cambiar esta configuración, seleccione el texto (DeleteCommand) en la ventana Propiedades y elija (New) en la lista desplegable. Esto borrará la configuración de las propiedades CommandText, CommandType y Parameters. A continuación, establezca la propiedad CommandType en StoredProcedure y escriba el nombre del procedimiento almacenado para el CommandText (dbo.Categories_Delete). Si se asegura de escribir las propiedades en este orden, primero el CommandType y después el CommandText, Visual Studio rellenará automáticamente la colección Parámetros. Si no escribe estas propiedades en este orden, tendrá que agregar manualmente los parámetros mediante el Editor de colección de parámetros. En cualquier caso, es prudente hacer clic en los puntos suspensivos de la propiedad Parámetros para abrir el Editor de colección de parámetros para comprobar que se han realizado los cambios correctos de configuración de parámetros (vea la Figura 16). Si no ve ningún parámetro en el cuadro de diálogo, agregue el parámetro @CategoryID manualmente (no es necesario agregar el parámetro @RETURN_VALUE).

Ensure That the Parameters Settings are Correct

Figura 16: Asegurarse de que la configuración de parámetros es correcta

Una vez actualizado el DAL, la eliminación de una categoría eliminará automáticamente todos sus productos asociados y lo hará bajo el ámbito de una transacción. Para comprobarlo, vuelva a la página Actualizar y eliminar datos binarios existentes y haga clic en el botón Eliminar de una de las categorías. Con un solo clic del mouse, se eliminará la categoría y todos sus productos asociados.

Nota:

Antes de probar el procedimiento almacenado Categories_Delete, que eliminará una serie de productos junto con la categoría seleccionada, puede ser prudente realizar una copia de seguridad de la base de datos. Si usa la base de datos de NORTHWND.MDF en App_Data, simplemente cierre Visual Studio y copie los archivos MDF y LDF en App_Data a alguna otra carpeta. Después de probar la funcionalidad, puede restaurar la base de datos cerrando Visual Studio y reemplazando los archivos MDF y LDF actuales en App_Data por las copias de seguridad.

Resumen

Aunque el asistente de TableAdapter generará automáticamente procedimientos almacenados para nosotros, hay ocasiones en las que es posible que ya tengamos estos procedimientos almacenados creados o quiera crearlos manualmente o con otras herramientas en su lugar. Para dar cabida a estos escenarios, TableAdapter también se puede configurar para que apunte a un procedimiento almacenado existente. En este tutorial hemos visto cómo agregar manualmente procedimientos almacenados a una base de datos a través del entorno de Visual Studio y cómo conectar los métodos de TableAdapter a estos procedimientos almacenados. También hemos examinado los comandos de T-SQL y el patrón de script que se usan para iniciar, confirmar y revertir transacciones desde dentro de un procedimiento almacenado.

¡Feliz programación!

Acerca del autor

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

Agradecimientos especiales a

Esta serie de tutoriales fue revisada por muchos revisores de gran ayuda. Los clientes principales de este tutorial fueron Hilton Geisenow, S ren Jacob Lauritsen y Teresa Murphy. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com.