Compartir a través de


Insertar, actualizar y eliminar datos con SqlDataSource (C#)

de Scott Mitchell

Descargar PDF

En los tutoriales anteriores hemos aprendido cómo el control ObjectDataSource permite insertar, actualizar y eliminar datos. El control SqlDataSource admite las mismas operaciones, pero el enfoque es diferente y en este tutorial se muestra cómo configurar SqlDataSource para insertar, actualizar y eliminar datos.

Introducción

Como se describe en Introducción a la inserción, actualización y eliminación, el control GridView proporciona funcionalidades integradas de actualización y eliminación, mientras que los controles DetailsView y FormView incluyen compatibilidad con la inserción junto con la funcionalidad de edición y eliminación. Estas funcionalidades de modificación de datos se pueden conectar directamente a un control de origen de datos sin necesidad de escribir una línea de código. Información general sobre la inserción, actualización y eliminación examinados mediante ObjectDataSource para facilitar la inserción, actualización y eliminación con los controles GridView, DetailsView y FormView. Como alternativa, sqlDataSource se puede usar en lugar de ObjectDataSource.

Recuerde que para admitir la inserción, actualización y eliminación, con ObjectDataSource necesitamos especificar los métodos de capa de objeto que se invocarán para realizar la acción de inserción, actualización o eliminación. Con el SqlDataSource, es necesario proporcionar las instrucciones SQL INSERT, UPDATE, y DELETE (o procedimientos almacenados) para ejecutar. Como veremos en este tutorial, estas instrucciones se pueden crear manualmente o se pueden generar automáticamente mediante el Asistente para configurar orígenes de datos de SqlDataSource.

Nota:

Puesto que ya hemos analizado las funcionalidades de inserción, edición y eliminación de los controles GridView, DetailsView y FormView, este tutorial se centrará en configurar el control SqlDataSource para admitir estas operaciones. Si necesita profundizar en la implementación de estas características en GridView, DetailsView y FormView, vuelva a los tutoriales de edición, inserción y eliminación de datos, empezando por Una introducción a la inserción, actualización y eliminación.

Paso 1: Especificar instrucciones INSERT, UPDATE y DELETE

Como hemos visto en los últimos dos tutoriales, para recuperar datos de un control SqlDataSource, es necesario establecer dos propiedades:

  1. ConnectionString, que especifica a qué base de datos se va a enviar la consulta y
  2. SelectCommand, que especifica la instrucción SQL ad-hoc o el nombre del procedimiento almacenado que se va a ejecutar para devolver los resultados.

Para SelectCommand los valores con parámetros, los valores de parámetro se especifican a través de la colección SqlDataSource; la colección SelectParameters puede incluir valores codificados de forma fija, valores de fuente común de parámetros (campos de cadena de consulta, variables de sesión, valores de control web, etc.) o pueden asignarse programáticamente. Cuando se invoca el método del control SqlDataSource Select() mediante programación o automáticamente desde un control web de datos, se establece una conexión a la base de datos, los valores de parámetro se asignan a la consulta y el comando se transfiere a la base de datos. A continuación, los resultados se devuelven como DataSet o DataReader, según el valor de la propiedad del DataSourceMode control.

Junto con la selección de datos, el control SqlDataSource se puede usar para insertar, actualizar y eliminar datos, proporcionando las instrucciones SQL INSERT, UPDATE y DELETE de la misma manera. Simplemente asigne las propiedades InsertCommand, UpdateCommand y DeleteCommand a las instrucciones SQL INSERT, UPDATE y DELETE que se deben ejecutar. Si las instrucciones tienen parámetros (como casi siempre lo harán), inclúyelos en las InsertParameters, UpdateParameters y DeleteParameters colecciones.

Una vez que se haya especificado un valor de InsertCommand, UpdateCommand o DeleteCommand, la opción de Habilitar inserción, Habilitar edición o Habilitar eliminación en la etiqueta inteligente del control web de datos correspondiente estará disponible. Para ilustrar esto, vamos a tomar un ejemplo de la Querying.aspx página que creamos en el tutorial Consulta de datos con el control SqlDataSource y aumentarlo para incluir funcionalidades de eliminación.

Comience abriendo las páginas InsertUpdateDelete.aspx y Querying.aspx desde la carpeta SqlDataSource. En la página del Diseñador Querying.aspx, seleccione SqlDataSource y GridView del primer ejemplo (los controles ProductsDataSource y GridView1). Después de seleccionar los dos controles, vaya al menú Editar y elija Copiar (o simplemente presione Ctrl+C). A continuación, vaya al Diseñador de InsertUpdateDelete.aspx y pegue los controles. Después de mover los dos controles a InsertUpdateDelete.aspx, pruebe la página en un explorador. Debería ver los valores de las ProductIDcolumnas , ProductNamey UnitPrice para todos los registros de la Products tabla de base de datos.

Todos los productos se enumeran, ordenados por ProductID

Figura 1: Todos los productos se enumeran, ordenados por ProductID (haga clic para ver la imagen de tamaño completo)

Agregar las propiedades DeleteCommand y DeleteParameters de SqlDataSource

En este punto, tenemos un objeto SqlDataSource que simplemente devuelve todos los registros de la Products tabla y un GridView que representa estos datos. Nuestro objetivo es ampliar este ejemplo para permitir que el usuario elimine productos a través de GridView. Para lograr esto, necesitamos especificar valores para las propiedades DeleteCommand y DeleteParameters del control SqlDataSource y, a continuación, configurar el GridView para admitir la eliminación.

Las DeleteCommand propiedades y DeleteParameters se pueden especificar de varias maneras:

  • Mediante la sintaxis declarativa
  • En la ventana de Propiedades del Diseñador
  • En la pantalla Especificar una instrucción SQL personalizada o un procedimiento almacenado en el Asistente para configurar orígenes de datos
  • Mediante el botón Avanzado de la pantalla para especificar columnas desde una vista en el asistente para configurar el origen de datos, que generará automáticamente la instrucción SQL y la colección de parámetros usada en las propiedades DELETE y DeleteCommand.

Examinaremos cómo crear automáticamente la declaración en el DELETE Paso 2. Por ahora, vamos a usar la ventana Propiedades en el Diseñador, aunque la opción Configurar origen de datos o sintaxis declarativa funcionaría igual.

En el Diseñador en InsertUpdateDelete.aspx, haga clic en el SqlDataSource y, a continuación, abra la Ventana de Propiedades (seleccione Ventana de Propiedades en el menú Ver o simplemente presione F4). Seleccione la propiedad DeleteQuery, que abrirá un conjunto de puntos suspensivos.

Captura de pantalla que muestra la ventana Propiedades ProductsDataSource con la propiedad DeleteQuery seleccionada.

Figura 2: Seleccionar la propiedad DeleteQuery en la ventana Propiedades

Nota:

SqlDataSource no tiene una propiedad DeleteQuery. En realidad, DeleteQuery es una combinación de las propiedades DeleteCommand y DeleteParameters y solo aparece en la ventana de propiedades cuando se visualiza la ventana mediante el Diseñador. Si está viendo la ventana Propiedades en la vista Origen, en su lugar encontrará la propiedad DeleteCommand.

Haga clic en los puntos suspensivos de la propiedad DeleteQuery para abrir el cuadro de diálogo Editor de comandos y parámetros (vea la figura 3). En este cuadro de diálogo puede especificar la DELETE instrucción SQL y especificar los parámetros. Escriba la siguiente consulta en el DELETE cuadro de texto de comando (ya sea manualmente o mediante el Generador de consultas, si lo prefiere):

DELETE FROM Products
WHERE ProductID = @ProductID

A continuación, haga clic en el botón Actualizar parámetros para agregar el @ProductID parámetro a la lista de parámetros siguientes.

Captura de pantalla que muestra la ventana Editor de comandos y parámetros con el parámetro <span class= @ProductID agregado a la lista de parámetros de comando DELETE". />

Figura 3: Seleccionar la propiedad DeleteQuery en la ventana Propiedades (haga clic para ver la imagen de tamaño completo)

No proporcione un valor para este parámetro (deje la fuente de este parámetro en Ninguno). Una vez que agreguemos soporte para eliminación a GridView, GridView proporcionará automáticamente este valor de parámetro, utilizando el valor de su colección DataKeys para la fila en la que se hizo clic en el botón Eliminar.

Nota:

El nombre del parámetro usado en la DELETE consulta debe ser el mismo que el nombre del DataKeyNames valor en GridView, DetailsView o FormView. Es decir, el parámetro de la instrucción DELETE se denomina @ProductID intencionadamente (en lugar de, por ejemplo, @ID), porque el nombre de columna de clave principal de la tabla Products (y, por tanto, el valor de DataKeyNames en el GridView) es ProductID.

Si el nombre del parámetro y el valor de DataKeyNames no coinciden, GridView no puede asignar automáticamente al parámetro el valor de la colección DataKeys.

Después de escribir la información relacionada con la eliminación en el cuadro de diálogo Comando y Editor de parámetros, haga clic en Aceptar y vaya a la vista Origen para examinar el marcado declarativo resultante:

<asp:SqlDataSource ID="ProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]"
    DeleteCommand="DELETE FROM Products WHERE ProductID = @ProductID">
    <DeleteParameters>
        <asp:Parameter Name="ProductID" />
    </DeleteParameters>
</asp:SqlDataSource>

Tenga en cuenta la adición de la DeleteCommand propiedad, así como la <DeleteParameters> sección y el objeto parámetro denominado productID.

Configuración de GridView para eliminar

Con la DeleteCommand propiedad agregada, la etiqueta inteligente GridView ahora contiene la opción Habilitar eliminación. Continúe y active esta casilla. Como se describe en Introducción a la inserción, actualización y eliminación, esto hace que GridView agregue un CommandField con su ShowDeleteButton propiedad establecida en true. Como se muestra en la figura 4, cuando se visita la página a través de un explorador, se incluye un botón Eliminar. Pruebe esta página eliminando algunos productos.

Cada fila GridView ahora incluye un botón Eliminar

Figura 4: Cada fila GridView ahora incluye un botón Eliminar (haga clic para ver la imagen de tamaño completo)

Al hacer clic en un botón Eliminar, se produce un postback. GridView asigna al parámetro el valor del elemento de la colección ProductID para la fila cuyo botón Eliminar fue clicado, e invoca el método DataKeys de SqlDataSource. A continuación, el control SqlDataSource se conecta a la base de datos y ejecuta la DELETE instrucción . GridView vuelve a enlazar a SqlDataSource, volviendo y mostrando el conjunto actual de productos (que ya no incluye el registro recién eliminado).

Nota:

Dado que GridView utiliza su colección DataKeys para rellenar los parámetros de SqlDataSource, es fundamental que la propiedad DataKeyNames de GridView se establezca en las columnas que constituyen la clave principal y que SqlDataSource SelectCommand devuelva estas columnas. Además, es importante que el nombre del parámetro en el SqlDataSource DeleteCommand esté establecido en @ProductID. Si la propiedad DataKeyNames no está establecida o el parámetro no se denomina @ProductsID, al hacer clic en el botón Eliminar provocará un postback, pero no se eliminará realmente ningún registro.

En la figura 5 se muestra esta interacción gráficamente. Consulte el tutorial Examinar los eventos asociados con la inserción, actualización y eliminación para obtener una explicación más detallada sobre la cadena de eventos asociados a la inserción, actualización y eliminación de un control web de datos.

Al hacer clic en el botón Eliminar de GridView, se invoca el método Delete() de SqlDataSource.

Figura 5: Hacer clic en el botón Eliminar en GridView invoca el método SqlDataSource Delete()

Paso 2: Generar automáticamente las instrucciones INSERT, UPDATE y DELETE

Según lo examinado en el Paso 1, las instrucciones SQL INSERT, UPDATE y DELETE se pueden especificar a través de la ventana de Propiedades o la sintaxis declarativa del control. Sin embargo, este enfoque requiere que escribamos a mano las instrucciones SQL, lo cual puede ser monótono y propenso a errores. Afortunadamente, el asistente de configuración del origen de datos ofrece una opción para que las sentencias INSERT, UPDATE, y DELETE se generen automáticamente al usar la pantalla de especificación de columnas de una vista de tabla.

Vamos a explorar esta opción de generación automática. Agregue un control DetailsView al Diseñador en InsertUpdateDelete.aspx y establezca su propiedad ID en ManageProducts. A continuación, en la etiqueta inteligente DetailsView, elija crear un nuevo origen de datos y cree un objeto SqlDataSource denominado ManageProductsDataSource.

Crear un nuevo objeto SqlDataSource denominado ManageProductsDataSource

Figura 6: Crear un nuevo objeto SqlDataSource con nombre ManageProductsDataSource (haga clic para ver la imagen de tamaño completo)

En el Asistente para configurar orígenes de datos, opte por usar la NORTHWINDConnectionString cadena de conexión y haga clic en Siguiente. En la pantalla Configurar la instrucción Select, deje seleccionado el botón de radio Especificar columnas de una tabla o vista y elija la tabla Products de la lista desplegable. Seleccione las ProductIDcolumnas , ProductName, UnitPricey Discontinued de la lista de casillas.

Utilizando la tabla de productos, devuelva las columnas ProductID, ProductName, UnitPrice y Discontinued

Figura 7: Usar la Products tabla, devolver las columnas ProductID, ProductName, UnitPrice y Discontinued (Haga clic para ver la imagen en tamaño completo)

Para generar automáticamente las instrucciones INSERT, UPDATE y DELETE basadas en la tabla y columnas seleccionadas, haga clic en el botón Avanzado y active la casilla de verificación Generar instrucciones INSERT, UPDATE y DELETE.

Marque la casilla Generar instrucciones INSERT, UPDATE y DELETE.

Figura 8: Comprobar la casilla de verificación Generar INSERT instrucciones, UPDATE, y DELETE

La casilla Generar INSERT, UPDATE, e DELETE instrucciones solo se podrá seleccionar si la tabla seleccionada tiene una clave principal y la columna de clave principal (o columnas) se incluyen en la lista de columnas devueltas. La casilla Usar simultaneidad optimista, que se vuelve seleccionable una vez activada la casilla Generar INSERT, UPDATE, y DELETE sentencias, aumentará las cláusulas de las sentencias resultantes WHERE y UPDATE para proporcionar un control de simultaneidad optimista. Por ahora, deje esta casilla desactivada; Examinaremos la simultaneidad optimista con el control SqlDataSource en el siguiente tutorial.

Después de activar la casilla Generar INSERT, UPDATE y DELETE declaraciones, haga clic en Aceptar para volver a la pantalla Configurar declaración Select; luego haga clic en Siguiente y por último en Finalizar, para completar el asistente para configurar el origen de datos. Tras completar el asistente, Visual Studio agregará BoundFields a DetailsView para las columnas ProductID, ProductName, y UnitPrice, y un CheckBoxField para la columna Discontinued. En la etiqueta inteligente de DetailsView, marca la opción Habilitar paginación para permitir que los usuarios que visiten esta página naveguen por los productos. Borre también las propiedades Width y Height de DetailsView.

Tenga en cuenta que la etiqueta inteligente tiene las opciones Habilitar inserción, Habilitar edición y Habilitar eliminación disponibles. Esto se debe a que SqlDataSource contiene valores para sus InsertCommand, UpdateCommandy DeleteCommand, como se muestra en la sintaxis declarativa siguiente:

<asp:DetailsView ID="ManageProducts" runat="server" AllowPaging="True"
    AutoGenerateRows="False" DataKeyNames="ProductID"
    DataSourceID="ManageProductsDataSource" EnableViewState="False">
    <Fields>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID"
            InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="ProductName"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
            SortExpression="UnitPrice" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="ManageProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    DeleteCommand=
        "DELETE FROM [Products] WHERE [ProductID] = @ProductID"
    InsertCommand=
        "INSERT INTO [Products] ([ProductName], [UnitPrice], [Discontinued])
         VALUES (@ProductName, @UnitPrice, @Discontinued)"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice], [Discontinued]
         FROM [Products]"
    UpdateCommand=
        "UPDATE [Products] SET [ProductName] = @ProductName,
         [UnitPrice] = @UnitPrice, [Discontinued] = @Discontinued
         WHERE [ProductID] = @ProductID">
    <DeleteParameters>
        <asp:Parameter Name="ProductID" Type="Int32" />
    </DeleteParameters>
    <UpdateParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="Discontinued" Type="Boolean" />
        <asp:Parameter Name="ProductID" Type="Int32" />
    </UpdateParameters>
    <InsertParameters>
        <asp:Parameter Name="ProductName" Type="String" />
        <asp:Parameter Name="UnitPrice" Type="Decimal" />
        <asp:Parameter Name="Discontinued" Type="Boolean" />
    </InsertParameters>
</asp:SqlDataSource>

Observe cómo el control SqlDataSource ha tenido valores establecidos automáticamente para sus InsertCommandpropiedades , UpdateCommandy DeleteCommand . El conjunto de columnas al que se hace referencia en las propiedades InsertCommand y UpdateCommand se basa en las de la SELECT instrucción. Es decir, en lugar de tener todas las columnas Products en InsertCommand y UpdateCommand, solo hay las columnas especificadas en SelectCommand (menos ProductID, que se omite porque es una IDENTITY columna, cuyo valor no se puede cambiar cuando se edita y que se asigna automáticamente al insertar). Además, para cada parámetro de las propiedades InsertCommand, UpdateCommand y DeleteCommand, hay parámetros correspondientes en las colecciones InsertParameters, UpdateParameters y DeleteParameters.

Para activar las características de modificación de datos de DetailsView, active las opciones Habilitar inserción, Habilitar edición y Habilitar eliminación en su etiqueta inteligente. Esto agrega un CommandField con sus propiedades ShowInsertButton, ShowEditButton y ShowDeleteButton establecidas en true.

Visite la página en un explorador y anote los botones Editar, Eliminar y Nuevo incluidos en DetailsView. Al hacer clic en el botón Editar, DetailsView se convierte en modo de edición, mostrando cada BoundField cuya propiedad ReadOnly está establecida en false (el valor predeterminado) como un cuadro de texto, y CheckBoxField como una casilla de verificación.

La interfaz de edición predeterminada de DetailsView

Figura 9: La interfaz de edición predeterminada de DetailsView (haga clic para ver la imagen de tamaño completo)

Del mismo modo, puede eliminar el producto seleccionado actualmente o agregar un nuevo producto al sistema. Puesto que la InsertCommand instrucción solo funciona con las ProductNamecolumnas , UnitPricey Discontinued , las otras columnas tienen NULL o su valor predeterminado asignado por la base de datos al insertar. Al igual que con ObjectDataSource, si en InsertCommand faltan columnas de la tabla de base de datos que no permiten NULL y no tienen un valor predeterminado, al intentar ejecutar la instrucción INSERT se producirá un error SQL.

Nota:

Las interfaces de inserción y edición de DetailsView carecen de cualquier tipo de personalización o validación. Para agregar controles de validación o para personalizar las interfaces, debe convertir BoundFields a TemplateFields. Consulte los tutoriales Agregar controles de validación a las interfaces de edición e inserción y personalización de la interfaz de modificación de datos para obtener más información.

Además, tenga en cuenta que para actualizar y eliminar, DetailsView usa el valor del DataKey producto actual, que solo está presente si la DataKeyNames propiedad está configurada. Si la edición o eliminación parece no tener ningún efecto, asegúrese de que la DataKeyNames propiedad está establecida.

Limitaciones de la generación automática de instrucciones SQL

Dado que la opción Generar INSERT, UPDATE e DELETE instrucciones solo está disponible al seleccionar columnas de una tabla, para consultas más complejas tendrá que escribir sus propias INSERT, UPDATE y DELETE instrucciones, así como hicimos en el paso 1. Normalmente, las instrucciones SQL SELECT utilizan JOIN s para recuperar datos de una o varias tablas de búsqueda para fines de visualización (como recuperar el campo de la tabla Categories al mostrar la información del producto). Al mismo tiempo, es posible que deseemos permitir al usuario editar, actualizar o insertar datos en la tabla principal (Productsen este caso).

Aunque las INSERT, UPDATE y DELETE instrucciones se pueden escribir manualmente, tenga en cuenta la siguiente sugerencia de ahorro de tiempo. Inicialmente, configure SqlDataSource para que extraiga los datos justo de la Products tabla. Use el asistente para configurar el origen de datos en la pantalla Especificar columnas de una tabla o vista, para que pueda generar automáticamente las instrucciones INSERT, UPDATE, y DELETE. Después de completar el asistente, elija configurar SelectQuery desde la ventana Propiedades (o, como alternativa, vuelva al Asistente para configurar orígenes de datos, pero use la opción Especificar una instrucción SQL personalizada o un procedimiento almacenado). A continuación, actualice la SELECT instrucción para incluir la JOIN sintaxis. Esta técnica ofrece las ventajas de ahorro de tiempo de las instrucciones SQL generadas automáticamente y permite una instrucción más personalizada SELECT .

Otra limitación de generar automáticamente las instrucciones INSERT, UPDATE y DELETE es que las instrucciones INSERT y UPDATE se basan en las columnas devueltas por las instrucciones SELECT. Sin embargo, es posible que tengamos que actualizar o insertar más o menos campos. Por ejemplo, en el ejemplo del paso 2, quizás queremos que UnitPrice BoundField sea de solo lectura. En ese caso, no debería aparecer en el UpdateCommand. O bien, es posible que deseemos establecer el valor de un campo de tabla que no aparezca en GridView. Por ejemplo, al agregar un nuevo registro, es posible que deseemos que el QuantityPerUnit valor se establezca en TODO .

Si se requieren estas personalizaciones, debe hacerlos manualmente, ya sea a través de la ventana Propiedades, la opción Especificar una instrucción SQL personalizada o un procedimiento almacenado en el asistente, o a través de la sintaxis declarativa.

Nota:

Al agregar parámetros que no tienen campos correspondientes en el control web de datos, tenga en cuenta que estos valores de parámetros deberán asignarse valores de alguna manera. Estos valores pueden ser: codificados de forma rígida directamente en InsertCommand o UpdateCommand; pueden provenir de algún origen predefinido (la cadena de consulta, el estado de sesión, los controles web de la página, etc.); o se pueden asignar mediante programación, como se ha visto en el tutorial anterior.

Resumen

Para que los controles web de datos usen sus funcionalidades integradas de inserción, edición y eliminación, el control de origen de datos al que están enlazados debe ofrecer dicha funcionalidad. Para el SqlDataSource, esto significa que las instrucciones SQL INSERT, UPDATE y DELETE deben asignarse a las propiedades InsertCommand, UpdateCommand y DeleteCommand. Estas propiedades y las colecciones de parámetros correspondientes se pueden agregar manual o generar automáticamente mediante el Asistente para configurar orígenes de datos. En este tutorial se examinaron ambas técnicas.

Hemos examinado el uso de la simultaneidad optimista con ObjectDataSource en el tutorial Implementación de simultaneidad optimista . El control SqlDataSource también proporciona compatibilidad con la simultaneidad optimista. Como se indica en el paso 2, al generar automáticamente las INSERT instrucciones, UPDATE y DELETE, el asistente ofrece la opción "Usar concurrencia optimista". Como veremos en el siguiente tutorial, el uso de la concurrencia optimista con SqlDataSource modifica las cláusulas en las instrucciones WHERE y UPDATE para asegurarse de que los valores de las otras columnas no han cambiado desde que los datos se mostraron por última vez en la página.

¡Feliz programación!

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 en 24 horas. Se puede contactar con él en mitchell@4GuysFromRolla.com.