NCapas o NLayer
A lo largo de mi carrera he aprendido multiples lenguajes de programacion desde C standar hasta lenguajes de mas alto nivel en este caso de .Net. especificamente hablando de programacion con CSharp, y bueno me gustaria compartir con ustedes con un proyecto generico de NCapas o NLayers.
Comencemos.
ACCESP A DATOS
En este primero blog se implementara una aplicacion basada en ADO.Net y tiene la siguiente estructura.
Todas las capas usan el proyecto de Entidades que son nada mas que la represtacion de tablas de la base de datos en Clases
Usaremos una base de datos encontrada clasica que cualquiera puede crear.
Para generar la cadena de conexion solo hacemos un copy paste de la conexion que se puede hacer haciendo uso de Visual Studio..
Siguiendo los pasos de conexion a una DB por VS desplegamos la vista Server Explorer danlole click derecho y propiedades de la conexion podremos ver la cadena de conexion ya generada.
Guardamos la cadena de conexion generada para poderlo invocar desde el Configuration Manager
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="Colegio" providerName="System.Data.SqlClient" connectionString="Data Source=line2;Initial Catalog=Colegio;Integrated Security=True" /> </connectionStrings> </configuration>
Comezamos creando un proyecto ClassLibray denominado DAL (Data Access Layer) es nuestra capa base de conexion a la Base de datos y creamos la estructura de directorios DAO, Genero y Utils esto para tener agrupado nuestras clases en un debido nameSpace.
Las clases iniciales a crear son las encontradas en Generic
Iniciamos creando la interface IDataAccess la cual abstrae la logica de conexion y obtencion de registros.
using System.Collections.Generic; using System.Data; using System.Data.SqlClient; namespace DAL.Generic { public interface IDataAccess { SqlDataReader GetReader(string sql, List<SqlParameter> listParam= null ); object GetScalar(string sql, List<SqlParameter> listParam = null); DataSet GetDataSet(string sql, List<SqlParameter> listParam = null); int ExecuteNonQuery(string sql, List<SqlParameter> listParam = null, bool isTransaction = false, CommandType commandType = CommandType.Text); } }
Implementado la interface en nuestra clase DaoTemplate esta clase nos proveera las herramientas basicas de obtension de registros desde la DB.
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; namespace DAL.Generic { public class DaoTemplate : IDataAccess { private SqlConnection GetConetion() { SqlConnection sqlConnection = new SqlConnection(ConfigurationManager.AppSettings["Colegio"].ToString()); return sqlConnection; } public SqlDataReader GetReader(string sql, List<SqlParameter> parameters = null) { } } public object GetScalar(string sql, List<SqlParameter> parameters = null) { SqlConnection conn = this.GetConetion(); } return obj; } public DataSet GetDataSet(string sql, List<SqlParameter> listParam = null) { SqlConnection conn = this.GetConetion(); return ds; } public int ExecuteNonQuery(string sql, List<SqlParameter> listParam = null, bool isTransaction = false, CommandType commandType = CommandType.Text) { { throw; } return res; } } }
El siguiente paso es crear nuestra interface de operaciones CRUD(Create Read Update Delete) o tambiem llamado ABM. en el cual abstraemos las operacions basicas de una entidad
1 2 3 4 5 6 7 8 9 10 11 12 13 | using System.Collections.Generic; namespace DAL.Generic { public interface IBaseCrud<Entity, Key> { List<Entity> GetAll(); Entity GetById(Key id); bool update(Entity entity); bool Add(Entity entity); bool Delete(Key value); } } |
Donde
Entidy es la entidad generica que queremos implementar CRUD
Key es la tipo de la llave primaria de nuestro mapeo de DB por lo general es entero pero en otras ocaciones es de tipo string. Haciendo uso de DaoTemplate podemos crear las operacion basicas, se opto por usar Procedimientos Almacenados es decir q en toda operacion se invocaran mediante procedimientos almacenados.
Haremos uso de un Mapeador de propiedades y tambien uso de Constantes prefijas
Ejm sp_sel_[NombreEntidad]
sp_ins_[NombreEntidad]
sp_del_[NombreEntidad]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using DAL.Utils; namespace DAL.Generic { public class BaseCrud<Entity, Key> : IBaseCrud<Entity, Key> { private DaoTemplate daoTemplate; private MapperEntity<Entity> mapper; public string Pkey { get; set; } public BaseCrud() { daoTemplate = new DaoTemplate(); mapper = new MapperEntity<Entity>(); } public bool Add(Entity entity) { string strSql = AppConst.SP_INSERT + typeof(Entity).Name.ToLower() + " "; List<SqlParameter> sqlParameters = new List<SqlParameter>(); Dictionary<string, object> columns = mapper.ParamentersFromEntity(entity, Pkey); foreach (var column in columns) { SqlParameter param = new SqlParameter(column.Key, column.Value); sqlParameters.Add(param); } int result = daoTemplate.ExecuteNonQuery(strSql, sqlParameters, false, CommandType.StoredProcedure); return result > 0 ? true : false; } public bool Delete(Key value) { string strSql = AppConst.SP_DELETE + typeof(Entity).Name.ToLower() + " "; List<SqlParameter> sqlParameters = new List<SqlParameter>(); SqlParameter param = new SqlParameter(Pkey, value); sqlParameters.Add(param); int result = daoTemplate.ExecuteNonQuery(strSql, sqlParameters, false, CommandType.StoredProcedure); return result > 0 ? true : false; } public List<Entity> GetAll() { string strSql = AppConst.SP_SELECT + typeof(Entity).Name.ToLower() + " "; DataSet result = daoTemplate.GetDataSet(strSql, null); return DataTablesToList.ConvertDataTable<Entity>(result.Tables[0]); } public Entity GetById(Key id) { throw new NotImplementedException(); } public bool update(Entity entity) { throw new NotImplementedException(); } private List<SqlParameter> GetParameters(Entity entity) { List<SqlParameter> lstParameters = new List<SqlParameter>(); foreach (var propertyInfo in entity.GetType().GetProperties()) { var name = propertyInfo.Name; Object value = propertyInfo.GetValue(this, null); SqlParameter param = new SqlParameter(name, value); lstParameters.Add(param); } return lstParameters; } } } |
Hasta aqui hemos creado la clase generica para nuestras entidades procederemos a implementar una de ellas para ello haremos el uso del proyecto de Entidades q son la representacion del modelo de la DB en clases.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using DAL.Generic; using ET; namespace DAL.Dao { public class RolImpl: BaseCrud<Rol, int> { public RolImpl() { this.Pkey = "Id"; } } } |
La clase la llamaremos RolImpl (como Rol Implementacion) esta clase al heredar de BaseCrud contedra las operaciones CRUD, ademas de ello aca podemos extender en nuevos metodos para complementar algun tipo de operacion,
las demas implementaciones a las entidades las puedes crear tu mismo ya que ahora resulta completamente sencillo implementar un crud solamente heredando de BaseCrud.
Con esto finalizamos la primera parte de Acceso a Datos generico usando tencnologia ADO.Net






No hay comentarios:
Publicar un comentario