Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Note
La DataSet clase y las clases relacionadas son tecnologías heredadas de .NET Framework de principios de los años 2000 que permiten a las aplicaciones trabajar con datos en memoria mientras las aplicaciones están desconectadas de la base de datos. Las tecnologías son especialmente útiles para las aplicaciones que permiten a los usuarios modificar datos y conservar los cambios de nuevo en la base de datos. Aunque los conjuntos de datos son una tecnología probada de éxito, el enfoque recomendado para las nuevas aplicaciones .NET es usar Entity Framework Core. Entity Framework proporciona una manera más natural de trabajar con datos tabulares como modelos de objetos y tiene una interfaz de programación más sencilla.
Cuando se crea una aplicación que manipula datos en una base de datos, normalmente se realizan tareas como definir cadenas de conexión, insertar datos y ejecutar procedimientos almacenados. Al seguir este artículo, puede descubrir cómo interactuar con una base de datos desde una aplicación de Windows Forms formularios sobre datos (FOD) mediante Visual C# o Visual Basic y ADO.NET. Todas las tecnologías de datos de .NET, incluidos los conjuntos de datos, LINQ (Language-Integrated Query) a SQL y Entity Framework, en última instancia realizan pasos similares a los que se muestran en este artículo.
En este artículo se muestra cómo obtener rápidamente datos de una base de datos. Si la aplicación necesita modificar los datos de maneras notriviales y actualizar la base de datos, considere la posibilidad de usar Entity Framework y el enlace de datos. Al hacerlo, los controles de la interfaz de usuario se sincronizan automáticamente con los cambios en los datos subyacentes.
Para acceder al código completo de este tutorial, consulte el repositorio de GitHub de documentos de Visual Studio para C# y Visual Basic.
Important
Para mantener el código sencillo, no se incluye el control de excepciones listo para producción.
Prerequisites
Visual Studio con las cargas de trabajo de procesamiento y almacenamiento de datos y desarrollo de escritorio de .NET instaladas. Para instalarlos, abra el Instalador de Visual Studio y elija Modificar junto a la versión de Visual Studio que desea modificar.
SQL Server Express LocalDB. Si no tiene SQL Server Express LocalDB, puede instalarlo desde la página de descarga de SQL Server.
En este artículo se da por supuesto que está familiarizado con la funcionalidad básica del IDE de Visual Studio. También supone que puede crear una aplicación de Windows Forms, agregar formularios a un proyecto, agregar botones y otros controles a los formularios, establecer propiedades de control y codificar eventos sencillos. Si no está familiarizado con estas tareas, complete el tutorial Creación de una aplicación de Windows Forms en Visual Studio con C# o creación de una aplicación de Windows Forms en Visual Studio con Visual Basic antes de iniciar este tutorial.
Configuración de la base de datos de ejemplo
Cree la base de datos de ejemplo siguiendo estos pasos:
En Visual Studio, abra la ventana Explorador de servidores.
Haga clic con el botón derecho en Conexiones de datos y elija Crear nueva base de datos de SQL Server.
En Nombre del servidor, escriba (localdb)\mssqllocaldb.
En Nuevo nombre de base de datos, escriba Ventas y, a continuación, elija Aceptar.
Visual Studio crea una base de datos Sales vacía en el nodo Conexiones de datos en el Explorador de servidores.
Haga clic con el botón derecho en la conexión Datos de ventas y seleccione Nueva consulta.
Se abre una ventana del editor de consultas.
Copie el script de Transact-SQL de Sales en el Portapapeles.
Pegue el script T-SQL en la ventana del editor de consultas y seleccione Ejecutar.
Después de un breve tiempo, la consulta termina de ejecutarse y se crean los objetos de base de datos. La base de datos contiene dos tablas: Customer y Orders. Estas tablas no contienen datos inicialmente, pero puede agregar datos al ejecutar la aplicación que cree. La base de datos también contiene cinco procedimientos almacenados básicos.
Crear los formularios y agregar controles
Cree un proyecto de C# o Visual Basic con la plantilla Aplicación de Windows Forms (.NET Framework) y asígneles el nombre SimpleDataApp.
Visual Studio crea el proyecto y varios archivos, incluido un formulario windows vacío denominado Form1.
En el Explorador de soluciones, agregue dos formularios Windows Forms al proyecto para que tenga un total de tres formularios y asígneles los nombres siguientes:
Navigation
NewCustomer
FillOrCancel
Para cada formulario, agregue los cuadros de texto, los botones y otros controles que se muestran en las ilustraciones siguientes. Para cada control, establezca las propiedades que describen las tablas.
Note
El cuadro de grupo y los controles de etiqueta agregan claridad, pero no se usan en el código.
Formulario Navigation
Controles para el formulario de navegación
Texto Control Tipo de control Propiedades de control Agregar una cuenta Button Nombre = btnGoToAdd Rellenar o cancelar un pedido Button Nombre = btnGoToFillOrCancel Exit Button Nombre = btnExit Formulario NewCustomer
Controles para el formulario NewCustomer
Texto de etiqueta/de control Tipo de control Propiedades de control Nombre de cliente TextBox Nombre = txtCustomerName ID de cliente TextBox Nombre = txtCustomerID
SoloLectura = VerdaderoCrear cuenta Button Nombre = btnCreateAccount Importe del pedido NumericUpdown Nombre = numOrderAmount
Posiciones decimales = 0
Máximo = 5000Fecha de pedido DateTimePicker Nombre = dtpOrderDate
Formato = CortoRealizar pedido Button Nombre = btnPlaceOrder Finish Button Nombre = btnAddFinish Agregar otra cuenta Button Nombre = btnAddAnotherAccount Formulario de Completar o Cancelar
Controles para el formulario FillOrCancel
Texto de etiqueta/de control Tipo de control Propiedades de control Id. de pedido TextBox Nombre = txtOrderID Buscar pedido Button Nombre = btnFindByOrderID Si se envía un pedido... DateTimePicker Nombre = dtpFillDate
Formato = Corto(None) DataGridView Nombre = dgvCustomerOrders
SoloLectura = Verdadero
Encabezados de filas visibles = FalseCancelar pedido Button Nombre = btnCancelOrder Procesar pedido Button Nombre = btnFillOrder Finish Button Nombre = btnFinishUpdates
Almacenar la cadena de conexión
Cuando la aplicación intenta abrir una conexión a la base de datos, la aplicación debe tener acceso a la cadena de conexión. Para evitar la necesidad de escribir la cadena manualmente en cada formulario, almacene la cadena en el archivo App.config en el proyecto. A continuación, cree un método que devuelva la cadena cuando se llame al método desde cualquier formulario de la aplicación.
Para buscar la cadena de conexión:
En el Explorador de servidores, haga clic con el botón derecho en la conexión de datos Sales y, a continuación, elija Propiedades.
Busque la propiedad Cadena de conexión y copie su valor de cadena en el Portapapeles.
Para almacenar la cadena de conexión en el proyecto:
En el Explorador de soluciones, realice uno de los pasos siguientes, en función del tipo de proyecto:
Para un proyecto de C#, expanda el nodo Propiedades en el proyecto y, a continuación, abra el archivo Settings.settings .
Para un proyecto de Visual Basic, seleccione Mostrar todos los archivos, expanda el nodo Mi proyecto y, a continuación, abra el archivo Settings.settings .
En la columna Nombre , escriba connString.
En la lista Tipo, seleccione (Cadena de conexión).
En la lista Ámbito, elija Aplicación.
En la columna Valor, escriba la cadena de conexión (sin comillas externas) y después guarde los cambios.
Caution
En una aplicación real, debe almacenar la cadena de conexión de forma segura, como se describe en Cadenas de conexión y archivos de configuración. Para obtener la mejor seguridad, use un método de autenticación que no dependa de almacenar una contraseña en la cadena de conexión. Por ejemplo, autenticación de Windows para una base de datos de SQL Server local. Para obtener más información, consulte Guardar y editar cadenas de conexión.
Escribir el código para los formularios
Esta sección contiene breves información general sobre lo que hace cada formulario. También proporciona el código que define la lógica subyacente al seleccionar un botón en el formulario.
Formulario de navegación
El formulario navegación se abre al ejecutar la aplicación e incluye los botones siguientes:
Agregar una cuenta: abre el formulario NewCustomer .
Rellenar o cancelar pedidos: abre el formulario FillOrCancel .
Salir: cierra la aplicación.
Convertir el formulario de navegación en el formulario de inicio
Para proyectos de C#:
En Explorador de soluciones, abra Program.cs.
Cambie la
Application.Runlínea a:Application.Run(new Navigation());
Para proyectos de Visual Basic:
En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y elija Propiedades.
En el Diseñador de proyectos, seleccione la pestaña Aplicación y, a continuación, seleccione Navegación en la lista Objeto de inicio .
Creación de controladores de eventos generados automáticamente para el formulario de navegación
Para crear métodos de controlador de eventos vacíos, haga doble clic en cada uno de los tres botones del formulario navegación. Al hacer doble clic en un botón, se agrega código generado automáticamente en el archivo de código del Diseñador, lo que permite que una selección de botón genere un evento.
Si decide copiar y pegar código directamente en los archivos de código en lugar de usar la acción de doble clic en el diseñador, asegúrese de establecer el controlador de eventos en el método correcto:
En la ventana Propiedades del archivo de código del formulario, cambie a la pestaña Eventos mediante el botón de la barra de herramientas del rayo.
Busque la propiedad Click y compruebe que su valor es el método de controlador de eventos correcto.
Adición de código para la lógica del formulario de navegación
En la página de código del formulario de Navegación, complete los cuerpos de los métodos para los tres controladores de eventos para la selección de botones, tal como se muestra en el código siguiente.
/// <summary>
/// Opens the NewCustomer form as a dialog box,
/// which returns focus to the calling form when it is closed.
/// </summary>
private void btnGoToAdd_Click(object sender, EventArgs e)
{
Form frm = new NewCustomer();
frm.Show();
}
/// <summary>
/// Opens the FillorCancel form as a dialog box.
/// </summary>
private void btnGoToFillOrCancel_Click(object sender, EventArgs e)
{
Form frm = new FillOrCancel();
frm.ShowDialog();
}
/// <summary>
/// Closes the application (not just the Navigation form).
/// </summary>
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
Formulario NewCustomer
Cuando escriba un nombre de cliente y, a continuación, seleccione el botón Crear cuenta , el formulario NewCustomer crea una cuenta de cliente y SQL Server devuelve un valor IDENTITY como el nuevo identificador de cliente. A continuación, puede realizar un pedido para la nueva cuenta especificando una cantidad y una fecha de pedido y seleccionando el botón Realizar pedido .
Creación de controladores de eventos generados automáticamente para el formulario NewCustomer
Cree un controlador de eventos Click vacío para cada botón del formulario NewCustomer haciendo doble clic en cada uno de los cuatro botones. Al hacer doble clic en los botones también se agrega código generado automáticamente en el archivo de código del Diseñador que permite seleccionar un botón para generar un evento.
Adición de código para la lógica de formulario NewCustomer
Para completar la lógica del formulario NewCustomer, siga estos pasos:
Incluya el espacio de nombres
System.Data.SqlClienten el ámbito para que no tenga que usar los nombres completos de sus miembros.
Agregue algunas variables y métodos auxiliares a la clase .
// Storage for IDENTITY values returned from database. private int parsedCustomerID; private int orderID; /// <summary> /// Verifies that the customer name text box is not empty. /// </summary> private bool IsCustomerNameValid() { if (txtCustomerName.Text == "") { MessageBox.Show("Please enter a name."); return false; } else { return true; } } /// <summary> /// Verifies that a customer ID and order amount have been provided. /// </summary> private bool IsOrderDataValid() { // Verify that CustomerID is present. if (txtCustomerID.Text == "") { MessageBox.Show("Please create customer account before placing order."); return false; } // Verify that Amount isn't 0. else if ((numOrderAmount.Value < 1)) { MessageBox.Show("Please specify an order amount."); return false; } else { // Order can be submitted. return true; } } /// <summary> /// Clears the form data. /// </summary> private void ClearForm() { txtCustomerName.Clear(); txtCustomerID.Clear(); dtpOrderDate.Value = DateTime.Now; numOrderAmount.Value = 0; this.parsedCustomerID = 0; }
Complete los cuerpos del método para los cuatro controladores de eventos de selección de botón.
/// <summary> /// Creates a new customer by calling the Sales.uspNewCustomer stored procedure. /// </summary> private void btnCreateAccount_Click(object sender, EventArgs e) { if (IsCustomerNameValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create a SqlCommand, and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspNewCustomer", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add input parameter for the stored procedure and specify what to use as its value. sqlCommand.Parameters.Add(new SqlParameter("@CustomerName", SqlDbType.NVarChar, 40)); sqlCommand.Parameters["@CustomerName"].Value = txtCustomerName.Text; // Add the output parameter. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Direction = ParameterDirection.Output; try { connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Customer ID is an IDENTITY value from the database. this.parsedCustomerID = (int)sqlCommand.Parameters["@CustomerID"].Value; // Put the Customer ID value into the read-only text box. this.txtCustomerID.Text = Convert.ToString(parsedCustomerID); } catch { MessageBox.Show("Customer ID was not returned. Account could not be created."); } finally { connection.Close(); } } } } } /// <summary> /// Calls the Sales.uspPlaceNewOrder stored procedure to place an order. /// </summary> private void btnPlaceOrder_Click(object sender, EventArgs e) { // Ensure the required input is present. if (IsOrderDataValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create SqlCommand and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspPlaceNewOrder", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add the @CustomerID input parameter, which was obtained from uspNewCustomer. sqlCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Int)); sqlCommand.Parameters["@CustomerID"].Value = this.parsedCustomerID; // Add the @OrderDate input parameter. sqlCommand.Parameters.Add(new SqlParameter("@OrderDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@OrderDate"].Value = dtpOrderDate.Value; // Add the @Amount order amount input parameter. sqlCommand.Parameters.Add(new SqlParameter("@Amount", SqlDbType.Int)); sqlCommand.Parameters["@Amount"].Value = numOrderAmount.Value; // Add the @Status order status input parameter. // For a new order, the status is always O (open). sqlCommand.Parameters.Add(new SqlParameter("@Status", SqlDbType.Char, 1)); sqlCommand.Parameters["@Status"].Value = "O"; // Add the return value for the stored procedure, which is the order ID. sqlCommand.Parameters.Add(new SqlParameter("@RC", SqlDbType.Int)); sqlCommand.Parameters["@RC"].Direction = ParameterDirection.ReturnValue; try { //Open connection. connection.Open(); // Run the stored procedure. sqlCommand.ExecuteNonQuery(); // Display the order number. this.orderID = (int)sqlCommand.Parameters["@RC"].Value; MessageBox.Show("Order number " + this.orderID + " has been submitted."); } catch { MessageBox.Show("Order could not be placed."); } finally { connection.Close(); } } } } } /// <summary> /// Clears the form data so another new account can be created. /// </summary> private void btnAddAnotherAccount_Click(object sender, EventArgs e) { this.ClearForm(); } /// <summary> /// Closes the form/dialog box. /// </summary> private void btnAddFinish_Click(object sender, EventArgs e) { this.Close(); }
Formulario de Rellenar o Cancelar
El formulario FillOrCancel ejecuta una consulta para devolver un pedido cuando escriba un identificador de pedido y, a continuación, seleccione el botón Buscar pedido . La fila devuelta aparece en una cuadrícula de datos de solo lectura. Puede marcar el pedido como cancelado (X) si selecciona el botón Cancelar pedido o puede marcar el pedido como rellenado (F) si selecciona el botón Rellenar pedido . Si vuelve a seleccionar el botón Buscar pedido , aparecerá la fila actualizada.
Creación de controladores de eventos generados automáticamente para el formulario FillOrCancel
Cree controladores de eventos Click vacíos para los cuatro botones del formulario FillOrCancel haciendo doble clic en los botones. Al hacer doble clic en los botones también se agrega código generado automáticamente en el archivo de código del Diseñador que permite seleccionar un botón para generar un evento.
Adición de código para la lógica de formulario FillOrCancel
Para completar la lógica del formulario FillOrCancel, siga estos pasos.
Incluya los dos espacios de nombres siguientes en el ámbito para que no tenga que usar los nombres completos de sus miembros.
Agregue una variable y un método auxiliar a la clase .
// Storage for the order ID value. private int parsedOrderID; /// <summary> /// Verifies that an order ID is present and contains valid characters. /// </summary> private bool IsOrderIDValid() { // Check for input in the Order ID text box. if (txtOrderID.Text == "") { MessageBox.Show("Please specify the Order ID."); return false; } // Check for characters other than integers. else if (Regex.IsMatch(txtOrderID.Text, @"^\D*$")) { // Show message and clear input. MessageBox.Show("Customer ID must contain only numbers."); txtOrderID.Clear(); return false; } else { // Convert the text in the text box to an integer to send to the database. parsedOrderID = Int32.Parse(txtOrderID.Text); return true; } }
Complete los cuerpos del método para los cuatro controladores de eventos de selección de botón.
/// <summary> /// Executes a t-SQL SELECT statement to obtain order data for a specified /// order ID, then displays it in the DataGridView on the form. /// </summary> private void btnFindByOrderID_Click(object sender, EventArgs e) { if (IsOrderIDValid()) { using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Define a t-SQL query string that has a parameter for orderID. const string sql = "SELECT * FROM Sales.Orders WHERE orderID = @orderID"; // Create a SqlCommand object. using (SqlCommand sqlCommand = new SqlCommand(sql, connection)) { // Define the @orderID parameter and set its value. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try { connection.Open(); // Run the query by calling ExecuteReader(). using (SqlDataReader dataReader = sqlCommand.ExecuteReader()) { // Create a data table to hold the retrieved data. DataTable dataTable = new DataTable(); // Load the data from SqlDataReader into the data table. dataTable.Load(dataReader); // Display the data from the data table in the data grid view. this.dgvCustomerOrders.DataSource = dataTable; // Close the SqlDataReader. dataReader.Close(); } } catch { MessageBox.Show("The requested order could not be loaded into the form."); } finally { // Close the connection. connection.Close(); } } } } } /// <summary> /// Cancels an order by calling the Sales.uspCancelOrder /// stored procedure on the database. /// </summary> private void btnCancelOrder_Click(object sender, EventArgs e) { if (IsOrderIDValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create the SqlCommand object and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspCancelOrder", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; try { // Open the connection. connection.Open(); // Run the command to execute the stored procedure. sqlCommand.ExecuteNonQuery(); } catch { MessageBox.Show("The cancel operation was not completed."); } finally { // Close connection. connection.Close(); } } } } } /// <summary> /// Fills an order by calling the Sales.uspFillOrder stored /// procedure on the database. /// </summary> private void btnFillOrder_Click(object sender, EventArgs e) { if (IsOrderIDValid()) { // Create the connection. using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.connString)) { // Create command and identify it as a stored procedure. using (SqlCommand sqlCommand = new SqlCommand("Sales.uspFillOrder", connection)) { sqlCommand.CommandType = CommandType.StoredProcedure; // Add the order ID input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@orderID", SqlDbType.Int)); sqlCommand.Parameters["@orderID"].Value = parsedOrderID; // Add the filled date input parameter for the stored procedure. sqlCommand.Parameters.Add(new SqlParameter("@FilledDate", SqlDbType.DateTime, 8)); sqlCommand.Parameters["@FilledDate"].Value = dtpFillDate.Value; try { connection.Open(); // Execute the stored procedure. sqlCommand.ExecuteNonQuery(); } catch { MessageBox.Show("The fill operation was not completed."); } finally { // Close the connection. connection.Close(); } } } } } /// <summary> /// Closes the form. /// </summary> private void btnFinishUpdates_Click(object sender, EventArgs e) { this.Close(); }
Prueba de la aplicación
Ejecute la aplicación e intente crear algunos clientes y pedidos para comprobar que todo funciona según lo previsto.
Para comprobar que la base de datos se actualiza con los cambios:
Abra el nodo Tablas en el Explorador de servidores.
Haga clic con el botón derecho en los nodos Clientes y pedidos y elija Mostrar datos de tabla.