Friday, August 25, 2017

ASP.NET MVC 5 + ADO.NET C# Parte 1

Sin mas preámbulos, empecemos a definir la estructura del proyecto.

Me gusta trabajar de la siguiente manera:

1. Entity: Entidades que representan las tablas de base de datos.
2. Data: Hace referencia a la capa Entity. En esta capa suelo usar una clase Connection y una interfaz IRepository, este viene a ser Repository Pattern. Aquí hace uso de nuestro querido amigo ADO.NET
3. Business: Hace referencia a la capa Entity y Data. Encapsula la logica de la Data y la retorna. Es nuestra tradicional capa de negocio. Es la que se comunicara directamente con nuestro proyecto web.
4. Web. Proyecto MVC5, hace referencia a la capa Entity y Business.


Para esta entrada, nos concentraremos en las dos primeras capas, vale decir, en la ENTITY y en la DATA.
Empecemos a crear una solución haciendo uso del Visual Studio 2017 (para mi caso) llamada Ventas. Vamos agregando proyectos a nuestra solución del tipo Class Library o Biblioteca de Clases por cada capa.

Primera Capa: Entity


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Entity
{
    public class Producto   
    {
        [Display(Name = "Código")]
        public int Id { get; set; }

        [Required(ErrorMessage = "El campo {0} es requerido.")]
        [Display(Name = "Nombre")]
        public string Nombre { get; set; }

        [Display(Name = "Descripción")]
        public String Descripcion { get; set; }

        [Required(ErrorMessage = "El campo {0} es requerido.")]
        [Display(Name ="Precio Unitario")]
        public double PrecioUnitario { get; set; }

        [Required(ErrorMessage = "El campo {0} es requerido.")]
        [Display(Name = "Stock")]
        public int Stock { get; set; }

        [Display(Name = "Estado")]
        public bool Estado { get; set; }

        public int IdCategoria { get; set; }
        public int IdProveedor { get; set; }

        public String Categoria { get; set; }
        public String Proveedor { get; set; }

        public String Nombre_Estado { get; set; }

    }
}

Ahora creamos el siguiente proyecto llamado Data.
Segunda Capa: Data


Nuestra capa Data tal como ya se dijo en las primeras lineas de esta entrada, tendremos una clase Connection, la estructura de la misma es como sigue:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace Data
{
    public class Connection
    {
        private static Connection _objCnn = null;
        private SqlConnection _cnn;
        private SqlTransaction _trn;

        private Connection()
        {
            _cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["cnnString"].ToString());
        }

        public static Connection InitializeConnection()
        {
            if (_objCnn == null)
            {
                _objCnn = new Connection();
            }
            return _objCnn;
        }

        public SqlConnection getCnn()
        {
            return _cnn;
        }
        public SqlConnection OpenConnection()
        {
            try
            {
                if (_cnn.State == ConnectionState.Open)
                {
                    return _cnn;
                }
                else
                {
                    _cnn.Open();
                }
                return _cnn;
            }
            catch (Exception)
            {

                throw;
            }
           
        }

        public void CloseConnection()
        {
            try
            {
                if (_cnn != null && _cnn.State != ConnectionState.Closed)
                {
                    _cnn.Close();
                }
            }
            catch (Exception)
            {

                throw;
            }
            
        }
    }
}

Ahora, construimos nuestro REPOSITORY PATTERN

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Data
{
    public interface IRepository where T : class
    {
        bool Insert(T model);
        bool Update(T model);
        bool Delete(int id);
        T GetById(int id);
        IEnumerable GetAll();
        IEnumerable SearchBy(T model);
    }
}


Ok, para finalizar la capa DATA, necesitamos crear una clase la cual implementará la interfaz creada anteriormente. Yo la llamé: ProductoRepository

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Entity;
using System.Data;
using System.Data.SqlClient;

namespace Data
{
    public class ProductoRepository : IRepository
    {
        private Connection _objCnn;
        //private SqlCommand _cmd;
        private SqlDataReader _reader;
        private string _tabla = string.Empty;

        public ProductoRepository()
        {
            _objCnn = Connection.InitializeConnection();
            _tabla = "Productos";
        }
        public bool Delete(int id)
        {
            int i;
            StringBuilder query = new StringBuilder();
            query.AppendFormat("DELETE FROM {0} WHERE id=@Id ", _tabla);

            try
            {
                using (SqlCommand cmd = new SqlCommand(query.ToString(), _objCnn.getCnn()))
                {
                    cmd.Parameters.AddWithValue("@id", id);
                    _objCnn.OpenConnection();
                    i = cmd.ExecuteNonQuery();
                }
            }
            catch (Exception)
            {

                throw;
            }
            finally
            {
                _objCnn.CloseConnection();
            }
            return i >= 1;
        }

        public IEnumerable GetAll()
        {
            StringBuilder query = new StringBuilder();
            query.AppendLine("SELECT p.id, p.nombre, p.descripcion, p.precio_unitario, p.stock, p.id_proveedor, p.id_categoria, p.estado, c.nombre as categoria, v.nombre as proveedor");
            query.AppendFormat("FROM {0} p ", _tabla);
            query.AppendLine("INNER JOIN Categorias c on c.id=p.id_categoria");
            query.AppendLine("INNER JOIN Proveedores v on v.id=p.id_proveedor");
            List listaProductos = new List();
            try
            {
                using (SqlCommand cmd = new SqlCommand(query.ToString(), _objCnn.getCnn()))
                {
                    _objCnn.OpenConnection();
                    _reader = cmd.ExecuteReader();
                    while (_reader.Read())
                    {   
                        Producto objProducto = new Producto();
                        objProducto.Id = Convert.ToInt32(_reader["id"].ToString());
                        objProducto.Nombre = _reader["nombre"].ToString();
                        objProducto.Descripcion = _reader["descripcion"].ToString();
                        objProducto.PrecioUnitario = Convert.ToDouble(_reader["precio_unitario"].ToString());
                        objProducto.Stock = Convert.ToInt32(_reader["stock"].ToString());
                        objProducto.IdProveedor = Convert.ToInt32(_reader["id_proveedor"].ToString());
                        objProducto.IdCategoria = Convert.ToInt32(_reader["id_categoria"].ToString());
                        objProducto.Estado = Convert.ToBoolean(_reader["estado"].ToString());
                        objProducto.Categoria = _reader["categoria"].ToString();
                        objProducto.Proveedor = _reader["proveedor"].ToString();
                        listaProductos.Add(objProducto);
                    }
                }
            }
            catch (Exception)
            {

                //throw;
            }
            finally
            {
                _objCnn.CloseConnection();
            }
            return listaProductos;
        }

        public Producto GetById(int id)
        {
            StringBuilder query = new StringBuilder();

            query.AppendLine("SELECT p.id, p.nombre, p.descripcion, p.precio_unitario, p.stock, p.id_proveedor, p.id_categoria, p.estado, c.nombre as categoria, v.nombre as proveedor, case p.estado when 1 then 'Activo' else 'Inactivo' end as nombre_estado");
            query.AppendFormat("FROM {0} p ", _tabla);
            query.AppendLine("INNER JOIN Categorias c on c.id=p.id_categoria");
            query.AppendLine("INNER JOIN Proveedores v on v.id=p.id_proveedor");
            query.AppendLine("WHERE p.id = @id");

            Producto p = new Producto();
            try
            {
                using (SqlCommand cmd = new SqlCommand(query.ToString(), _objCnn.getCnn()))
                {
                    _objCnn.OpenConnection();
                    cmd.Parameters.AddWithValue("@id", id);
                    _reader = cmd.ExecuteReader();
                    if (_reader != null && _reader.HasRows)
                    {
                        _reader.Read();
                        p.Id = Convert.ToInt32(_reader["id"].ToString());
                        p.Nombre = _reader["nombre"].ToString();
                        p.Descripcion = _reader["descripcion"].ToString();
                        p.PrecioUnitario = Convert.ToDouble(_reader["precio_unitario"].ToString());
                        p.Stock = Convert.ToInt32(_reader["stock"].ToString());
                        p.IdProveedor = Convert.ToInt32(_reader["id_proveedor"].ToString());
                        p.IdCategoria = Convert.ToInt32(_reader["id_categoria"].ToString());
                        p.Estado = Convert.ToBoolean(_reader["estado"].ToString());
                        p.Categoria = _reader["categoria"].ToString();
                        p.Proveedor = _reader["proveedor"].ToString();
                        p.Nombre_Estado = _reader["nombre_estado"].ToString();
                    }
                }
            }
            catch (Exception)
            {

                //throw;
            }
            finally
            {
                _objCnn.CloseConnection();
            }
            return p;
        }

        public bool Insert(Producto model)
        {
            //string msg = string.Empty;
            int i;
            StringBuilder query = new StringBuilder();
            query.AppendFormat("INSERT INTO {0} ", _tabla);
            query.AppendLine("(nombre, descripcion, precio_unitario, stock, id_proveedor, id_categoria, estado)");
            query.AppendLine("VALUES");
            query.AppendLine("(@nombre, @descripcion, @precio_unitario, @stock, @id_proveedor, @id_categoria, @estado)");
            //query.AppendLine(";SELECT SCOPE_IDENTITY()");

            try
            {
                using (SqlCommand cmd = new SqlCommand(query.ToString(), _objCnn.getCnn()))
                {
                    cmd.Parameters.AddWithValue("@nombre", model.Nombre);
                    cmd.Parameters.AddWithValue("@descripcion", model.Descripcion);
                    cmd.Parameters.AddWithValue("@precio_unitario", model.PrecioUnitario);
                    cmd.Parameters.AddWithValue("@stock", model.Stock);
                    cmd.Parameters.AddWithValue("@id_proveedor", model.IdProveedor);
                    cmd.Parameters.AddWithValue("@id_categoria", model.IdCategoria);
                    cmd.Parameters.AddWithValue("@estado", model.Estado);
                    _objCnn.OpenConnection();
                    //i = (int)cmd.ExecuteScalar();
                    i =cmd.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                //msg= ex.Message;
                throw new Exception(ex.Message);
            }
            finally
            {
                _objCnn.CloseConnection();
            }
            //return i;
            return i >= 1;
        }

        public IEnumerable SearchBy(Producto model)
        {
            StringBuilder query = new StringBuilder();
            query.AppendLine("SELECT p.id, p.nombre, p.descripcion, p.precio_unitario, p.stock, ");
            query.AppendLine("p.id_proveedor, p.id_categoria, p.estado, c.nombre as categoria, v.nombre as proveedor");
            query.AppendFormat("FROM {0} p ", _tabla);
            query.AppendLine("INNER JOIN Categorias c on c.id=p.id_categoria");
            query.AppendLine("INNER JOIN Proveedores v on v.id=p.id_proveedor");
            query.AppendLine("WHERE 1=1 and");

            if (model.Id > 0)
            {
                query.AppendLine("p.id=@id");
            }
            if (model.Nombre != string.Empty)
            {
                string condicion;
                condicion = (model.Id > 0) ? " and p.nombre like '%' + @nombre + '%' " : " p.nombre like '%' + @nombre + '%' ";
                query.AppendLine(condicion);
                //query.AppendLine("p.nombre like '%' + @nombre + '%' ");
            }
            
           List  listaProductos = new List();
            try
            {
                using (SqlCommand cmd = new SqlCommand(query.ToString(), _objCnn.getCnn()))
                {
                    _objCnn.OpenConnection();
                    cmd.Parameters.AddWithValue("@id", model.Id);
                    cmd.Parameters.AddWithValue("@nombre", model.Nombre);

                    _reader = cmd.ExecuteReader();
                    while (_reader.Read())
                    {
                        Producto objProducto = new Producto();
                        objProducto.Id = Convert.ToInt32(_reader["id"].ToString());
                        objProducto.Nombre = _reader["nombre"].ToString();
                        objProducto.Descripcion = _reader["descripcion"].ToString();
                        objProducto.PrecioUnitario = Convert.ToDouble(_reader["precio_unitario"].ToString());
                        objProducto.Stock = Convert.ToInt32(_reader["stock"].ToString());
                        objProducto.IdProveedor = Convert.ToInt32(_reader["id_proveedor"].ToString());
                        objProducto.IdCategoria = Convert.ToInt32(_reader["id_categoria"].ToString());
                        objProducto.Estado = Convert.ToBoolean(_reader["estado"].ToString());
                        objProducto.Categoria = _reader["categoria"].ToString();
                        objProducto.Proveedor = _reader["proveedor"].ToString();
                        listaProductos.Add(objProducto);
                    }
                }
            }
            catch (Exception)
            {

                //throw;
            }
            finally
            {
                _objCnn.CloseConnection();
            }
            return listaProductos;
        }

        public bool Update(Producto model)
        {
            int i;
            StringBuilder query = new StringBuilder();
            query.AppendFormat("UPDATE {0} ", _tabla);
            query.AppendLine("SET nombre = @nombre, descripcion = @descripcion, precio_unitario = @precio_unitario, stock = @stock,");
            query.AppendLine("id_proveedor = @id_proveedor, id_categoria = @id_categoria, estado = @estado");
            query.AppendLine("WHERE id = @id");

            try
            {
                using (SqlCommand cmd = new SqlCommand(query.ToString(), _objCnn.getCnn()))
                {
                    cmd.Parameters.AddWithValue("@nombre", model.Nombre);
                    cmd.Parameters.AddWithValue("@descripcion", model.Descripcion);
                    cmd.Parameters.AddWithValue("@precio_unitario", model.PrecioUnitario);
                    cmd.Parameters.AddWithValue("@stock", model.Stock);
                    cmd.Parameters.AddWithValue("@id_proveedor", model.IdProveedor);
                    cmd.Parameters.AddWithValue("@id_categoria", model.IdCategoria);
                    cmd.Parameters.AddWithValue("@estado", model.Estado);
                    cmd.Parameters.AddWithValue("@id", model.Id);
                    _objCnn.OpenConnection();
                    i = cmd.ExecuteNonQuery();
                }
            }
            catch (Exception)
            {
                return false;
                //throw;
            }
            finally
            {
                _objCnn.CloseConnection();
            }
            return i >= 1;
        }
    }
}

1 comment:

  1. Por favor me puedes ayudar con el proyecto a mi correo, porque tengo errores miguel_brionez@hotmail.com

    ReplyDelete