1. Entorno
- SQL Server 2008
- Visual Studio 2008
2. Introducción
2.1. Programación por capas
La programación por capas es un estilo de programación en el que el objetivo primordial es la separación de la lógica de negocios de la lógica de diseño. La ventaja principal de este estilo es que el desarrollo se puede llevar a cabo en varios niveles y, en caso de que sobrevenga algún cambio, sólo se ataca al nivel requerido sin tener que revisar entre código mezclado. Un buen ejemplo de este método de programación sería el modelo de interconexión de sistemas abiertos
2.2. Programación en tres capas
- Capa de presentación: es la que ve el usuario (también se la denomina "capa de usuario"), presenta el sistema al usuario, le comunica la información y captura la información del usuario en un mínimo de proceso (realiza un filtrado previo para comprobar que no hay errores de formato). Esta capa se comunica únicamente con la capa de negocio. También es conocida como interfaz gráfica y debe tener la característica de ser "amigable" (entendible y fácil de usar) para el usuario.
- Capa de negocio: es donde residen los programas que se ejecutan, se reciben las peticiones del usuario y se envían las respuestas tras el proceso. Se denomina capa de negocio (e incluso de lógica del negocio) porque es aquí donde se establecen todas las reglas que deben cumplirse. Esta capa se comunica con la capa de presentación, para recibir las solicitudes y presentar los resultados, y con la capa de datos, para solicitar al gestor de base de datos para almacenar o recuperar datos de él. También se consideran aquí los programas de aplicación.
- Capa de datos: es donde residen los datos y es la encargada de acceder a los mismos. Está formada por uno o más gestores de bases de datos que realizan todo el almacenamiento de datos, reciben solicitudes de almacenamiento o recuperación de información desde la capa de negocio.
3. Desarrollo
3.1. Creando el proyecto
Primero debemos de crear un proyecto con Visual Studio 2008, para eso abrimos el Visual Studio 2008 y nos vamos al menú de "Archivo-->Nuevo Proyecto". A nuestro proyecto le pondremos de nombre "SistemaVentas"
3.2. Agregando la Capa de Datos
Debemos de agregar a nuestro proyecto la capa de datos, para eso nos vamos al menu de "Archivo-->Agregar Nuevo Proyecto"
Y le pondremos como nombre "CapaDatos"
3.3. La clase Conexion
Para agregar una clase en C# debemos hacer clic derecho en la Capa de Datos y seleccionar la opción "Agregar-->Clase" y la clase que creamos se llamara "Conexion", que se encargara de guardar la cadena de conexión para poder conectarnos con nuestra base de datos que esta en SQL Server 2008 y la cual se llama BDTutorial.
La clase Conexion tendrá el siguiente código en C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; //Desarrollado por Adrián Sánchez namespace CapaDatos { public class Conexion { //La base de datos se llama BDTutorial //La ubicacion de base de datos esta de modo local y en una instancia que se llama SQL2008 //Utiliza seguridad integrada para conectarse a la base de datos public static string cn = "Data Source=.\\SQL2008;Initial Catalog=BDTutorial;Integrated Security=True"; } }
3.2. La clase Producto
Esta clase se encarga de conectar la tabla Producto con C#
using System; using System.Collections.Generic; using System.Text; //Impotaciones necesarias using System.Data; using System.Data.SqlClient; //Desarrollado por Adrián Sánchez namespace CapaDatos { public class Producto { private int var_codigoProducto; private string var_nombre; private decimal var_precio; //Constructor vacio public Producto() { } //Constructor con parametros public Producto( int codigoProducto, string nombre, decimal precio ) { this.var_codigoProducto = codigoProducto; this.var_nombre = nombre; this.var_precio = precio; } //Metodo utilizado para insertar un Producto public string Insertar(Producto varProducto) { string rpta = ""; SqlConnection sqlCon = new SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn; //2. Abrir la conexion de la BD sqlCon.Open(); //3. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon; sqlCmd.CommandText = "spI_Producto"; sqlCmd.CommandType = CommandType.StoredProcedure; //4. Agregar los parametros al comando //Establecemos los valores para el parametro @codigoProducto del Procedimiento Almacenado SqlParameter sqlParcodigoProducto = new SqlParameter(); sqlParcodigoProducto.ParameterName = "@codigoProducto"; sqlParcodigoProducto.SqlDbType = SqlDbType.Int; //Le declaramos que el parametro es de salida, porque obtendremos el codigo generado por la base de datos sqlParcodigoProducto.Direction = ParameterDirection.Output; sqlCmd.Parameters.Add(sqlParcodigoProducto); //Agregamos el parametro al comando //Establecemos los valores para el parametro @nombre del Procedimiento Almacenado SqlParameter sqlParnombre = new SqlParameter(); sqlParnombre.ParameterName = "@nombre"; sqlParnombre.SqlDbType = SqlDbType.VarChar; sqlParnombre.Size = 100; sqlParnombre.Value = varProducto.nombre; sqlCmd.Parameters.Add(sqlParnombre); //Agregamos el parametro al comando //Establecemos los valores para el parametro @precio del Procedimiento Almacenado SqlParameter sqlParprecio = new SqlParameter(); sqlParprecio.ParameterName = "@precio"; sqlParprecio.SqlDbType = SqlDbType.Decimal; sqlParprecio.Precision=18; sqlParprecio.Scale=2; sqlParprecio.Value = varProducto.precio; sqlCmd.Parameters.Add(sqlParprecio); //Agregamos el parametro al comando //5. Ejecutamos el commando rpta = sqlCmd.ExecuteNonQuery() == 1 ? "OK" : "No se inserto el producto de forma correcta"; } catch (Exception ex) { rpta = ex.Message; } finally { //6. Cerramos la conexion con la BD if (sqlCon.State == ConnectionState.Open) sqlCon.Close(); } return rpta; } //Metodo utilizado para actualizar un Producto public string Actualizar(Producto varProducto) { string rpta = ""; SqlConnection sqlCon = new SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn; //2. Abrir la conexion de la BD sqlCon.Open(); //3. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon; sqlCmd.CommandText = "spU_Producto"; sqlCmd.CommandType = CommandType.StoredProcedure; //4. Agregar los parametros al comando //Establecemos los valores para el parametro @codigoProducto del Procedimiento Almacenado SqlParameter sqlParcodigoProducto = new SqlParameter(); sqlParcodigoProducto.ParameterName = "@codigoProducto"; sqlParcodigoProducto.SqlDbType = SqlDbType.Int; sqlParcodigoProducto.Value = varProducto.codigoProducto; sqlCmd.Parameters.Add(sqlParcodigoProducto); //Agregamos el parametro al comando //Establecemos los valores para el parametro @nombre del Procedimiento Almacenado SqlParameter sqlParnombre = new SqlParameter(); sqlParnombre.ParameterName = "@nombre"; sqlParnombre.SqlDbType = SqlDbType.VarChar; sqlParnombre.Size = 100; sqlParnombre.Value = varProducto.nombre; sqlCmd.Parameters.Add(sqlParnombre); //Agregamos el parametro al comando //Establecemos los valores para el parametro @precio del Procedimiento Almacenado SqlParameter sqlParprecio = new SqlParameter(); sqlParprecio.ParameterName = "@precio"; sqlParprecio.SqlDbType = SqlDbType.Decimal; sqlParprecio.Precision = 18; sqlParprecio.Scale = 2; sqlParprecio.Value = varProducto.precio; sqlCmd.Parameters.Add(sqlParprecio); //Agregamos el parametro al comando //5. Ejecutamos el commando rpta = sqlCmd.ExecuteNonQuery() == 1 ? "OK" : "No se actualizo el producto de forma correcta"; } catch (Exception ex) { rpta = ex.Message; } finally { //6. Cerramos la conexion con la BD if (sqlCon.State == ConnectionState.Open) sqlCon.Close(); } return rpta; } //Metodo utilizado para obtener todos los productos de la base de datos public DataTable ObtenerProducto() { DataTable dtProducto = new DataTable("Producto"); SqlConnection sqlCon = new SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn; //2. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon;//La conexion que va a usar el comando sqlCmd.CommandText = "spF_Producto_All";//El comando a ejecutar sqlCmd.CommandType = CommandType.StoredProcedure;//Decirle al comando que va a ejecutar una sentencia SQL //3. No hay parametros //4. El DataAdapter que va a ejecutar el comando y es el encargado de llena el DataTable SqlDataAdapter sqlDat = new SqlDataAdapter(sqlCmd); sqlDat.Fill(dtProducto);//Llenamos el DataTable } catch (Exception ex) { dtProducto = null; } return dtProducto; } #region Metodos Get y Set public int codigoProducto { get { return var_codigoProducto; } set { var_codigoProducto = value; } } public string nombre { get { return var_nombre; } set { var_nombre = value; } } public decimal precio { get { return var_precio; } set { var_precio = value; } } #endregion } }
3.3. Clase DetalleVenta
Esta clase se encarga de conectar la tabla DetalleVenta con C#
using System; using System.Collections.Generic; using System.Text; //Impotaciones necesarias using System.Data; using System.Data.SqlClient; //Desarrollado por Adrián Sánchez namespace CapaDatos { public class DetalleVenta { private int var_codigoVenta; private int var_codigoProducto; private decimal var_cantidad; private decimal var_descuento; //Constructor vacio public DetalleVenta() { } //Constructor con parametros public DetalleVenta( int codigoVenta , int codigoProducto , decimal cantidad , decimal descuento ) { this.var_codigoVenta=codigoVenta; this.var_codigoProducto=codigoProducto; this.var_cantidad=cantidad; this.var_descuento=descuento; } //Metodo utilizado para insertar un DetalleVenta //Le pasamos la conexion y la transaccion por referencia, debido a que esos datos lo obtenemos //de la clase Venta y no deberiamos crear una nueva Conexion o una nueva Transaccion //sino la creada por la clase Venta public string Insertar(DetalleVenta varDetalleVenta, ref SqlConnection sqlCon, ref SqlTransaction sqlTra) { string rpta = ""; try { //1. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon; sqlCmd.Transaction = sqlTra; sqlCmd.CommandText = "spI_DetalleVenta"; sqlCmd.CommandType = CommandType.StoredProcedure; //4. Agregar los parametros al comando //Establecemos los valores para el parametro @codigoVenta del Procedimiento Almacenado SqlParameter sqlParcodigoVenta = new SqlParameter(); sqlParcodigoVenta.ParameterName = "@codigoVenta"; sqlParcodigoVenta.SqlDbType = SqlDbType.Int; sqlParcodigoVenta.Value = varDetalleVenta.codigoVenta; sqlCmd.Parameters.Add(sqlParcodigoVenta); //Agregamos el parametro al comando //Establecemos los valores para el parametro @codigoProducto del Procedimiento Almacenado SqlParameter sqlParcodigoProducto = new SqlParameter(); sqlParcodigoProducto.ParameterName = "@codigoProducto"; sqlParcodigoProducto.SqlDbType = SqlDbType.Int; sqlParcodigoProducto.Size = 4; sqlParcodigoProducto.Value = varDetalleVenta.codigoProducto; sqlCmd.Parameters.Add(sqlParcodigoProducto); //Agregamos el parametro al comando //Establecemos los valores para el parametro @cantidad del Procedimiento Almacenado SqlParameter sqlParcantidad = new SqlParameter(); sqlParcantidad.ParameterName = "@cantidad"; sqlParcantidad.SqlDbType = SqlDbType.Decimal; sqlParcantidad.Precision = 18; sqlParcantidad.Scale = 2; sqlParcantidad.Value = varDetalleVenta.cantidad; sqlCmd.Parameters.Add(sqlParcantidad); //Agregamos el parametro al comando //Establecemos los valores para el parametro @descuento del Procedimiento Almacenado SqlParameter sqlPardescuento = new SqlParameter(); sqlPardescuento.ParameterName = "@descuento"; sqlPardescuento.SqlDbType = SqlDbType.Decimal; sqlParcantidad.Precision = 18; sqlParcantidad.Scale = 2; sqlPardescuento.Value = varDetalleVenta.descuento; sqlCmd.Parameters.Add(sqlPardescuento); //Agregamos el parametro al comando //5. Ejecutamos el commando rpta = sqlCmd.ExecuteNonQuery() == 1 ? "OK" : "No se inserto el detalle de venta de forma correcta"; } catch (Exception ex) { rpta = ex.Message; } return rpta; } #region Metodos Get y Set public int codigoVenta { get { return var_codigoVenta; } set { var_codigoVenta = value; } } public int codigoProducto { get { return var_codigoProducto; } set { var_codigoProducto = value; } } public decimal cantidad { get { return var_cantidad; } set { var_cantidad = value; } } public decimal descuento { get { return var_descuento; } set { var_descuento = value; } } #endregion } }
3.4. Clase Venta
Esta clase se encarga de conectar la tabla Venta con C#
using System; using System.Collections.Generic; using System.Text; //Impotaciones necesarias using System.Data; using System.Data.SqlClient; //Desarrollado por Adrián Sánchez namespace CapaDatos { public class Venta { private int var_codigoVenta; private string var_cliente; private DateTime var_fecha; //Constructor vacio public Venta() { } //Constructor con parametros public Venta(int codigoVenta,string cliente,DateTime fecha) { this.var_codigoVenta=codigoVenta; this.var_cliente=cliente; this.var_fecha=fecha; } //Metodo utilizado para insertar un Venta public string Insertar(Venta varVenta, List<DetalleVenta> detalles) { string rpta = ""; SqlConnection sqlCon = new SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn; //2. Abrir la conexion de la BD sqlCon.Open(); //3. Establecer la transaccion SqlTransaction sqlTra = sqlCon.BeginTransaction(); //4. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon; sqlCmd.Transaction = sqlTra; sqlCmd.CommandText = "spI_Venta"; sqlCmd.CommandType = CommandType.StoredProcedure; //5. Agregar los parametros al comando //Establecemos los valores para el parametro @codigoVenta del Procedimiento Almacenado SqlParameter sqlParcodigoVenta = new SqlParameter(); sqlParcodigoVenta.ParameterName = "@codigoVenta"; sqlParcodigoVenta.SqlDbType = SqlDbType.Int; sqlParcodigoVenta.Direction = ParameterDirection.Output; sqlCmd.Parameters.Add(sqlParcodigoVenta); //Agregamos el parametro al comando //Establecemos los valores para el parametro @cliente del Procedimiento Almacenado SqlParameter sqlParcliente = new SqlParameter(); sqlParcliente.ParameterName = "@cliente"; sqlParcliente.SqlDbType = SqlDbType.VarChar; sqlParcliente.Size = 100; sqlParcliente.Value = varVenta.cliente; sqlCmd.Parameters.Add(sqlParcliente); //Agregamos el parametro al comando //6. Ejecutamos el commando rpta = sqlCmd.ExecuteNonQuery() == 1 ? "OK" : "No se inserto el detalle de venta de forma correcta"; if (rpta.Equals("OK")) { //Obtenemos el codigo de la venta que se genero por la base de datos this.codigoVenta=Convert.ToInt32(sqlCmd.Parameters["@codigoVenta"].Value); foreach(DetalleVenta det in detalles){ //Establecemos el codigo de la venta que se autogenero det.codigoVenta = this.codigoVenta; //Llamamos al metodo insertar de la clase DetalleVenta //y le pasamos la conexion y la transaccion que debe de usar rpta = det.Insertar(det, ref sqlCon, ref sqlTra); if (!rpta.Equals("OK")) { //Si ocurre un error al insertar un detalle de venta salimos del for break; } } } if (rpta.Equals("OK")) { //Se inserto todo los detalles y confirmamos la transaccion sqlTra.Commit(); } else { //Algun detalle no se inserto y negamos la transaccion sqlTra.Rollback(); } } catch (Exception ex) { rpta = ex.Message; } finally { //6. Cerramos la conexion con la BD if (sqlCon.State == ConnectionState.Open) sqlCon.Close(); } return rpta; } //Obtenemos la venta por el codigo generado public DataTable ObtenerVenta(int codigoVenta) { DataTable dtVenta = new DataTable("Venta"); SqlConnection sqlCon = new SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn; //2. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon;//La conexion que va a usar el comando sqlCmd.CommandText = "spF_Venta_One";//El comando a ejecutar sqlCmd.CommandType = CommandType.StoredProcedure;//Decirle al comando que va a ejecutar una sentencia SQL //3. Agregar los parametros al comando //Establecemos los valores para el parametro @codigoVenta del Procedimiento Almacenado SqlParameter sqlParcodigoVenta = new SqlParameter(); sqlParcodigoVenta.ParameterName = "@codigoVenta"; sqlParcodigoVenta.SqlDbType = SqlDbType.Int; sqlParcodigoVenta.Value = codigoVenta; sqlCmd.Parameters.Add(sqlParcodigoVenta); //Agregamos el parametro al comando //4. El DataAdapter que va a ejecutar el comando y es el encargado de llena el DataTable SqlDataAdapter sqlDat = new SqlDataAdapter(sqlCmd); sqlDat.Fill(dtVenta);//Llenamos el DataTable } catch (Exception ex) { dtVenta = null; } return dtVenta; } //Obtener todas las ventas public DataTable ObtenerVenta() { DataTable dtVenta = new DataTable("Venta"); SqlConnection sqlCon = new SqlConnection(); try { //1. Establecer la cadena de conexion sqlCon.ConnectionString = Conexion.cn; //2. Establecer el comando SqlCommand sqlCmd = new SqlCommand(); sqlCmd.Connection = sqlCon;//La conexion que va a usar el comando sqlCmd.CommandText = "spF_Venta_All";//El comando a ejecutar sqlCmd.CommandType = CommandType.StoredProcedure;//Decirle al comando que va a ejecutar una sentencia SQL //3. No hay parametros //4. El DataAdapter que va a ejecutar el comando y es el encargado de llena el DataTable SqlDataAdapter sqlDat = new SqlDataAdapter(sqlCmd); sqlDat.Fill(dtVenta);//Llenamos el DataTable } catch (Exception ex) { dtVenta = null; } return dtVenta; } #region Metodos Get y Set public int codigoVenta { get { return var_codigoVenta; } set { var_codigoVenta = value; } } public string cliente { get { return var_cliente; } set { var_cliente = value; } } public DateTime fecha { get { return var_fecha; } set { var_fecha = value; } } #endregion } }
4. Resumen
Al final deberíamos tener las siguientes clases
No hay comentarios.:
Publicar un comentario