0% encontró este documento útil (0 votos)
4 vistas24 páginas

Actividad 5 preguntas

vcvSDvcxS

Cargado por

Jamyl Zurita
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
4 vistas24 páginas

Actividad 5 preguntas

vcvSDvcxS

Cargado por

Jamyl Zurita
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 24

INGENIERÍA EN SISTEMAS

DESARROLLO DE SISTEMAS 1

Tema: Actividad 5

Estudiante:

Jamyl Zurita Pilinco

Docente:

Hugo Arnaldo Guzman Centellas

13 de noviembre del 2024 –Santa Cruz - Bolivia


ÍNDICE
DESARROLLO DE UN SISTEMA DE INFORMACIÓN CON UNA ARQUITECTURA
WINDOWS FORM Y BASE DE DATOS...............................................................................3
1. Componentes de conexión a base de datos................................................................3
Origen:...................................................................................................................................3
ilustración .1.........................................................................................................................4
2. Componentes de ejecución de comandos...................................................................4
Origen y finalidad................................................................................................................4
3. Componentes de cargado de tablas y consultas........................................................5
Origen y evolución:.............................................................................................................5
4. Manejo de datos en las interfaces de usuario.............................................................5
Origen y propósito:.............................................................................................................5
ilustración .2.........................................................................................................................6
5. Conexiones y accesos a datos desde la aplicación. dar 1 Ejemplos y
demostrar con 1 Ejercicio.....................................................................................................6
Origen y Propósito:...........................................................................................................6
6. Formularios de entrada de datos simples. Ejemplos y Ejercicios..........................8
Origen y propósito:.............................................................................................................8
7. Formularios de entrada de datos maestro-detalle. (en que consiste, ejemplo )
...................................................................................................................................................15
Origen y propósito:...........................................................................................................16
Componentes del Formulario Maestro-Detalle..........................................................17
MAPA MENTAL......................................................................................................................22
BIBLIOGRAFÍA:......................................................................................................................23
DESARROLLO DE UN SISTEMA DE INFORMACIÓN
CON UNA ARQUITECTURA WINDOWS FORM Y BASE
DE DATOS

1. Componentes de conexión a base de datos

Origen:
La idea de vincular bases de datos en software ganó popularidad junto con el
auge de los programas servidor-cliente durante las décadas de 1980 y 1990.
Al introducir .NET en 2002, Microsoft ofreció Active Data Objects
para .NET.NET), un conjunto de clases para conectar y manipular bases de
datos. Los elementos de enlace permiten establecer conductos seguros para
que el software interactúe con el marco de administración de datos (DAF).

Componentes principales:

La clase SQLConnection en ADO.NET permite la conectividad de bases de


datos con sistemas SQL Server. Emplea el Protocolo de control de
transmisión/Protocolo de Internet para la comunicación y requiere una cadena
de conexión que comprende un servidor, una base de datos y detalles de inicio
de sesión.

MySqlConnection: Enlace a bases de datos MySQL (formada en 1995 y


comprada por Oracle en 2010).

Para las bases de datos Oracle, emplea el protocolo OCI (Oracle Call
Interface).

Cada enlace emplea una cadena de enlace que se ajusta a un patrón particular
basado en la variedad de la base de datos. La cadena de enlace es vital ya
que proporciona los detalles necesarios para que la aplicación reconozca y se
conecte al almacenamiento de datos.
ilustración .1

2. Componentes de ejecución de comandos

Origen y finalidad.

ADO.NET implementó la clase Operación para ejecutar comandos SQL


en programas .NET. Esto permitió a los programadores consultar bases
de datos utilizando comandos SQL dentro del propio código. La
necesidad de realizar operaciones SQL precisas (sentencias o
alteraciones) dio lugar a la formación de estas clases.

Componentes principales.

• SqlCommand: ejecuta comandos SQL en SQL Server. Permite la


interacción con declaraciones SELECT, INSERT, UPDATE y DELETE.

• MySqlCommand: Para comandos SQL en MySQL.

• OracleCommand: Ejecuta sentencias SQL en bases de datos Oracle.

Tipos de comando:

• SELECCIONAR: Extraer datos.


• INSERTAR, ACTUALIZAR, ELIMINAR: Modificar o eliminar datos.

3. Componentes de cargado de tablas y consultas

Origen y evolución:

Con la expansión del software comercial en la década de 1990, los


programas requirieron un mecanismo para gestionar y organizar la
información en tablas almacenadas en la memoria. ADO.NET trajo
nuevas formas de conservar datos usando DataSet y DataTable, lo que
ayuda a ahorrar recursos porque no es necesario permanecer conectado
a la base de datos todo el tiempo.

Componentes clave:

 Un SqlDataAdapter crea un vínculo entre la base de datos y el


DataSet y facilita las operaciones fuera de línea.

• DataSet: un contenedor en memoria para datos en formato de tabla.

Cada línea incorpora una recopilación de información fáctica discreta.

4. Manejo de datos en las interfaces de usuario

Origen y propósito:

A medida que las aplicaciones pasaron de la línea de comandos a las


interfaces gráficas en la década de 1990, surgió la necesidad de
herramientas para presentar datos a los usuarios en una forma visual
fácil de usar. En .NET, controles como DataGridView, TextBox y
ComboBox le permiten recopilar y mostrar datos en la interfaz.

Controles principales:

• DataGridView: Le permite mostrar datos en una tabla, ideal para


registros grandes.

• TextBox: adecuado para un cómodo control de entrada de texto.


• ComboBox: lista desplegable que permite seleccionar opciones y
conectarse a una fuente de datos.

ilustración .2

5. Conexiones y accesos a datos desde la aplicación. dar 1 Ejemplos y


demostrar con 1 Ejercicio.

Se requieren conexiones y acceso a datos desde la aplicación para que la


aplicación pueda comunicarse con la base de datos y realizar operaciones de
consulta, inserción, actualización y eliminación (operaciones CRUD). En .NET,
este acceso a los datos se logra principalmente a través de ADO.NET (Objetos
de datos activos para .NET), un conjunto de clases de biblioteca diseñadas
para facilitar la conexión y la manipulación de datos en diferentes sistemas de
administración de bases de datos (DBMS).

Origen y Propósito:
Con el crecimiento de las aplicaciones empresariales y las aplicaciones cliente-
servidor, se necesita una plataforma estándar para permitir una comunicación
eficiente y segura entre las aplicaciones y sus bases de datos. ADO (Active
Data Objects) ha sido una de las primeras tecnologías de Microsoft para
conectarse a bases de datos desde la década de 1990. Posteriormente, con el
lanzamiento de .NET en 2002, se creó ADO.NET para modernizar y optimizar
esta conexión en las aplicaciones .NET.

Componentes clave de conexiones y acceso a datos:


• SqlConnection: este componente establece conexiones entre
aplicaciones .NET. y base de datos SQL Server.Es la base de la comunicación
y se encarga de abrir y cerrar canales de comunicación.

• SqlCommand: Le permite ejecutar comandos SQL en la base de datos. Se


puede utilizar con consultas (SELECT) o comandos de modificación (INSERT,
UPDATE, DELETE).

• SqlDataReader: permite leer datos en modo directo y de solo lectura y está


optimizado para mover grandes conjuntos de datos.

• SqlDataAdapter: facilita el trabajo. Carga datos en un DataSet o DataTable y


le permite trabajar sin conexión cargando los datos en la memoria y
manteniéndolos disponibles sin la necesidad de una conexión persistente.

Ejemplo de Conexión y Ejercicio:

 Ejemplo: Conectar a SQL Server con SqlConnection y realizar una


consulta.

Código:

using System.Data.SqlClient;
string connectionString = "Data Source=nombreServidor;Initial
Catalog=miBase;User ID=usuario;Password=contraseña;";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
Console.WriteLine("Conexión abierta.");
connection.Close();

Ejercicio: Crear una aplicación que consulte y muestre los registros de


Clientes en consola.
Código:

string query = "SELECT * FROM Clientes";


SqlCommand command = new SqlCommand(query, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine($"{reader["Nombre"]}, {reader["Apellido"]}");
}

6. Formularios de entrada de datos simples. Ejemplos y Ejercicios.

Los formularios simples de entrada de datos son el método principal para


recopilar y almacenar información en una base de datos a través de una
interfaz de usuario. Estos formularios permiten a los usuarios ingresar datos en
campos específicos y enviar esa información a la base de datos, generalmente
a través de un botón de acción como "Guardar" o "Enviar". Se utilizan
ampliamente en aplicaciones empresariales para permitir la recopilación de
datos estructurados y confiables.

Origen y propósito:
Desde el desarrollo de las primeras interfaces gráficas en la década de 1990,
los formularios de entrada de datos se han convertido en el método estándar
para recopilar información del usuario. En .NET, puede desarrollar formularios
fácilmente utilizando Windows Forms o WPF (Windows Presentation
Foundation), tecnologías de interfaz gráfica de usuario (GUI) proporcionadas
por Microsoft para desarrollar aplicaciones de escritorio. Los formularios
simples son ideales para aplicaciones CRUD (crear, leer, actualizar, eliminar),
donde cada formulario se puede diseñar para recopilar datos específicos de
cada objeto.

Componentes básicos de un formulario de entrada de datos simple:

1. Cuadro de texto (TextBox): registre el nombre, apellido, dirección y otro


texto.

2.Controles de selección (ComboBox, RadioButton, CheckBox): permiten


la selección entre opciones predefinidas.
3. Botón (Button): Cuando se presiona, realiza operaciones como "Guardar",
"Cancelar" o "Eliminar".

4. Etiqueta (Label): Describe o indica el propósito de cada campo en el


formulario.

Ejemplo de formulario de entrada de datos simple;

Ejemplo 1: Formulario Básico de Entrada de Datos

Supongamos que necesitas crear un formulario en una aplicación de Windows


Forms (WPF o WinForms) para ingresar datos de un cliente a una base de
datos. Este formulario incluiría campos como nombre, apellido, y correo
electrónico.

Los pasos que seguimos serán este:

Paso 1: Creación del formulario

1. Crea un formulario en Windows Forms con tres campos de texto


(TextBox) para ingresar el nombre, el apellido y el correo electrónico.
2. Agrega un botón de Guardar que, al hacer clic, guarde los datos en la
base de datos.

Paso 2: Código de ejemplo

Este es un ejemplo en C# para un formulario básico que inserta datos en una


tabla Clientes:

using System;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace EjemploFormulario
{
public partial class Form1 : Form
{
// Cadena de conexión a la base de datos
string connectionString = "Data Source=nombreServidor;Initial
Catalog=nombreBase;User ID=usuario;Password=contraseña;";

public Form1()
{
InitializeComponent();
}

private void btnGuardar_Click(object sender, EventArgs e)


{
// Validar que los campos no estén vacíos
if (string.IsNullOrWhiteSpace(txtNombre.Text) ||
string.IsNullOrWhiteSpace(txtApellido.Text) ||
string.IsNullOrWhiteSpace(txtCorreo.Text))
{
MessageBox.Show("Por favor, complete todos los campos.");
return;
}

// Insertar los datos en la base de datos


using (SqlConnection connection = new
SqlConnection(connectionString))
{
try
{
connection.Open();
string query = "INSERT INTO Clientes (Nombre, Apellido, Correo)
VALUES (@nombre, @apellido, @correo)";
using (SqlCommand command = new SqlCommand(query,
connection))
{
command.Parameters.AddWithValue("@nombre",
txtNombre.Text);
command.Parameters.AddWithValue("@apellido",
txtApellido.Text);
command.Parameters.AddWithValue("@correo",
txtCorreo.Text);

command.ExecuteNonQuery();
MessageBox.Show("Cliente guardado exitosamente.");
}
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}");
}
}
}
}
}

Explicación:

 TextBox: Los campos txtNombre, txtApellido, y txtCorreo son los


controles de entrada de datos en el formulario.
 SqlConnection: Establece la conexión con la base de datos.
 SqlCommand: Ejecuta la consulta SQL de inserción para agregar un
cliente a la base de datos.
 Validación: Se realiza una validación simple para asegurarse de que los
campos no estén vacíos antes de enviar los datos.

Ejercicio 1: Crear un formulario de entrada de datos

Objetivo: Crear un formulario para ingresar los datos de un producto, con los
siguientes campos:
 Nombre del producto
 Precio (campo numérico)
 Cantidad disponible

Requisitos:

1. El formulario debe incluir un botón Guardar.


2. La aplicación debe insertar los datos en la tabla Productos en una base
de datos.

Pasos a aseguir:

1. Diseña el formulario con los controles necesarios (TextBox para el


nombre del producto, el precio y la cantidad).
2. Usa un Button para que el usuario pueda enviar los datos.
3. Escribe el código que guarde los datos en la base de datos.

Ejemplo de código para insertar producto:


private void btnGuardar_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtNombreProducto.Text) ||
string.IsNullOrWhiteSpace(txtPrecio.Text) ||
string.IsNullOrWhiteSpace(txtCantidad.Text))
{
MessageBox.Show("Por favor, complete todos los campos.");
return;
}

using (SqlConnection connection = new SqlConnection(connectionString))


{
try
{
connection.Open();
string query = "INSERT INTO Productos (Nombre, Precio, Cantidad)
VALUES (@nombre, @precio, @cantidad)";
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@nombre",
txtNombreProducto.Text);
command.Parameters.AddWithValue("@precio",
decimal.Parse(txtPrecio.Text));
command.Parameters.AddWithValue("@cantidad",
int.Parse(txtCantidad.Text));

command.ExecuteNonQuery();
MessageBox.Show("Producto guardado exitosamente.");
}
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}");
}
}
}

Ejercicio 2: Validaciones en el formulario

Objetivo: Mejorar el formulario anterior añadiendo validaciones más detalladas.

Requisitos:

1. Verificar que el campo "Precio" sea un número decimal.


2. Verificar que la "Cantidad" sea un número entero positivo.
3. Si hay algún error, mostrar un mensaje adecuado al usuario.

Pasos a dseguir:

1. Validar el campo de precio: Asegúrate de que el precio ingresado sea


un número decimal.
2. Validar la cantidad: Asegúrate de que la cantidad sea un número
entero y mayor que 0.
3. Mostrar mensajes: Si alguna validación falla, mostrar un mensaje
adecuado y evitar que el formulario se envíe.

Ejemplo de validación para precio y cantidad:


private void btnGuardar_Click(object sender, EventArgs e)
{
// Validar que los campos no estén vacíos
if (string.IsNullOrWhiteSpace(txtNombreProducto.Text) ||
string.IsNullOrWhiteSpace(txtPrecio.Text) ||
string.IsNullOrWhiteSpace(txtCantidad.Text))
{
MessageBox.Show("Por favor, complete todos los campos.");
return;
}

// Validar que el precio sea un número decimal válido


if (!decimal.TryParse(txtPrecio.Text, out decimal precio))
{
MessageBox.Show("Por favor, ingrese un precio válido.");
return;
}

// Validar que la cantidad sea un número entero positivo


if (!int.TryParse(txtCantidad.Text, out int cantidad) || cantidad <= 0)
{
MessageBox.Show("Por favor, ingrese una cantidad válida mayor que 0.");
return;
}

using (SqlConnection connection = new SqlConnection(connectionString))


{
try
{
connection.Open();
string query = "INSERT INTO Productos (Nombre, Precio, Cantidad)
VALUES (@nombre, @precio, @cantidad)";
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@nombre",
txtNombreProducto.Text);
command.Parameters.AddWithValue("@precio", precio);
command.Parameters.AddWithValue("@cantidad", cantidad);

command.ExecuteNonQuery();
MessageBox.Show("Producto guardado exitosamente.");
}
}
catch (Exception ex)
{
MessageBox.Show($"Error: {ex.Message}");
}
}
}

Explicamos los ejercicios realizados para el entendimiento;

 Ejercicio 1: Crear un formulario básico para insertar datos en una tabla


de productos.
 Ejercicio 2: Mejorar el formulario con validaciones para asegurarse de
que los datos sean correctos antes de enviarlos a la base de datos.

los ejercicios nos permitirán practicar la creación de formularios de entrada de


datos en aplicaciones de escritorio, validando los datos y asegurando que la
información se guarde de manera correcta y eficiente.
7. Formularios de entrada de datos maestro-detalle. (en que consiste,
ejemplo )

Un formulario de ingreso de datos maestros-detallados es una interfaz de


usuario que le permite ingresar y administrar datos en dos niveles jerárquicos,
donde un conjunto de datos (datos maestros) tiene una relación de uno a
muchos con otro conjunto de datos (datos detallados). . Este tipo de formulario
se usa ampliamente en aplicaciones de bases de datos que administran
información relacionada al permitir a los usuarios administrar datos primarios y
sus registros secundarios.

Origen y propósito:
Las vistas maestras y detalladas son muy comunes en aplicaciones de bases
de datos empresariales para organizar datos. en forma de capas. Esta
estructura también se conoce como relación de uno a muchos, donde un
registro en la tabla principal (tabla maestra) puede tener múltiples registros
relacionados en la tabla secundaria (tabla de detalles).

¿En qué consiste el modelo maestro-esclavo?

En un formulario maestro de detalles, el formulario maestro representa la


entidad principal (registro maestro) y el formulario detallado muestra registros
relacionados o auxiliares que dependen del registro maestro. Un formulario
principal normalmente contiene información general y un formulario detallado
maneja información específica relacionada con ese formulario principal.

Ejemplo Práctico: Factura y Líneas de Detalle

Supongamos un formulario para agregar una factura junto con sus líneas de
detalle (productos adquiridos en esa factura). La base de datos tiene dos
tablas relacionadas:

1. Factura (Tabla Maestro):


o FacturaID (Clave primaria)
o Fecha
o Total

2. DetalleFactura (Tabla Detalle):


o DetalleID (Clave primaria)
o FacturaID (Clave foránea)
o ProductoID
o Cantidad
o Precio

El objetivo es que el usuario pueda seleccionar una factura (maestro) y agregar


múltiples productos a esa factura (detalle).

Componentes del Formulario Maestro-Detalle

1. Formulario Maestro:
o Campos para la información principal de la factura (por ejemplo,
Fecha y Total).
o Un control para seleccionar la factura, si se trata de una edición
de factura existente.

2. Formulario Detalle:
o Un subformulario o grid donde el usuario pueda agregar múltiples
productos (cada uno con campos como ProductoID, Cantidad,
Precio).
o La relación entre la factura y las líneas de detalle se mantiene
mediante un campo común (FacturaID).

3. Botones:
o Agregar (para agregar una nueva línea de detalle).
o Guardar (para guardar tanto la factura como las líneas de detalle
en la base de datos).

Código de Ejemplo en C# ;
Tenemos un formulario donde se ingresan tanto los datos de la factura como
las líneas de detalle, utilizando una base de datos SQL Server.

Pasos:

Paso 1: Formulario Maestro (Factura)

El formulario tiene campos para la información de la factura, como la fecha, el


total y un control (por ejemplo, un DataGridView) para ingresar las líneas de
detalle.

public partial class FormFactura : Form


{
// Cadena de conexión a la base de datos
string connectionString = "Data Source=nombreServidor;Initial
Catalog=nombreBase;User ID=usuario;Password=contraseña;";

public FormFactura()
{
InitializeComponent();
}

// Método para guardar la factura


private void btnGuardar_Click(object sender, EventArgs e)
{
// Validación de campos
if (string.IsNullOrWhiteSpace(txtFecha.Text) || dgvDetalle.Rows.Count ==
0)
{
MessageBox.Show("Por favor, ingrese la fecha de la factura y agregue
al menos un detalle.");
return;
}

using (SqlConnection connection = new SqlConnection(connectionString))


{
try
{
// Abrir conexión
connection.Open();
SqlTransaction transaction = connection.BeginTransaction();

// Insertar la factura (maestro)


string queryFactura = "INSERT INTO Factura (Fecha, Total)
OUTPUT INSERTED.FacturaID VALUES (@fecha, @total)";
SqlCommand commandFactura = new SqlCommand(queryFactura,
connection, transaction);
commandFactura.Parameters.AddWithValue("@fecha",
txtFecha.Text);
commandFactura.Parameters.AddWithValue("@total", txtTotal.Text);
int facturaID = (int)commandFactura.ExecuteScalar(); // Obtener el ID
de la factura insertada

// Insertar las líneas de detalle (detalle)


foreach (DataGridViewRow row in dgvDetalle.Rows)
{
if (row.IsNewRow) continue; // Ignorar la fila en blanco

string queryDetalle = "INSERT INTO DetalleFactura (FacturaID,


ProductoID, Cantidad, Precio) VALUES (@facturaID, @productoID, @cantidad,
@precio)";
SqlCommand commandDetalle = new SqlCommand(queryDetalle,
connection, transaction);
commandDetalle.Parameters.AddWithValue("@facturaID",
facturaID);
commandDetalle.Parameters.AddWithValue("@productoID",
row.Cells["ProductoID"].Value);
commandDetalle.Parameters.AddWithValue("@cantidad",
row.Cells["Cantidad"].Value);
commandDetalle.Parameters.AddWithValue("@precio",
row.Cells["Precio"].Value);
commandDetalle.ExecuteNonQuery();
}

// Confirmar transacción
transaction.Commit();
MessageBox.Show("Factura y detalles guardados exitosamente.");
}
catch (Exception ex)
{
// Revertir transacción en caso de error
MessageBox.Show($"Error: {ex.Message}");
}
}
}
}

Explicación del código

1. Formulario Maestro:
o Se captura la fecha de la factura y el total.
o Se validan los campos para asegurarse de que la factura tenga
información antes de guardar.

2. Guardar la factura:
o Primero, se inserta la factura en la tabla Factura y se obtiene su
FacturaID utilizando OUTPUT INSERTED.FacturaID.

3. Guardar las líneas de detalle:


o Después, se recorren las filas del DataGridView (donde se
muestran las líneas de detalle) e insertan los datos
correspondientes en la tabla DetalleFactura.
o Se usa una transacción para garantizar que ambas tablas se
guarden correctamente (si hay un error, se deshacen los
cambios).

4. Uso de transacciones:
o La inserción de la factura y los detalles se realiza dentro de una
transacción SQL para asegurar la consistencia de los datos. Si
ocurre un error en cualquier parte del proceso, se revertirán todos
los cambios.

Conceptos Clave para entender:

1. Relación principal-detalle. En una relación de uno a muchos, la tabla maestra


(facturas) tiene varias instancias en los detalles (filas de detalles).

2. Transacción: La transacción se utiliza para garantizar que los datos maestros


y los datos detallados se almacenen correctamente. Si algo sale mal en el
camino, todo se puede deshacer.

3.Interacción entre controles. En una forma "Maestro-Detalle", el control


maestro puede afectar el control de detalle. Por ejemplo, al seleccionar una
cuenta se cambian las filas de información que se muestran.
MAPA MENTAL
BIBLIOGRAFÍA:
 Microsoft. (2021). ADO.NET Overview. Microsoft. Recuperado de
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ado-net-overview

 Schmidt, A. (2014). Mastering Visual Studio 2013. Wiley. Recuperado de


https://www.wiley.com/en-us/Mastering+Visual+Studio+2013-p-9781118772009

 Bourne, J., & Sones, M. (2011). Beginning ASP.NET 4.5 in C#. Wiley. Recuperado
de :https://doi.org/10.1002/9781118194573

 Davis, J. (2016). Beginning ASP.NET 4.5.1: in C# and VB. Wiley. Recuperado de


https://www.wiley.com/en-us/Beginning+ASP.NET+4.5.1%3A+in+C%23+and+VB-p-
9781118765971

También podría gustarte