Buscar este blog

jueves, 5 de abril de 2018

EntityFramework + Patrón Repositorio

En tres artículos anteriores explique cómo utilizar ADO.NET y DataSet. En este artículo les voy a explicar cómo utilizar EntityFramework  y el patrón repositorio con dos gestores de bases de datos.

En este artículo no voy a explicar la sintaxis del lenguaje de consulta SQL ni MySQL, ni algunos pasos ya que se encuantra escrito en los tres artículos mencionados.

El código hablará por si solo:

Crearemos la clase conexión.


static class Connection
    {
       internal static string Connected()
       {
           var provider = ConfigurationManager.AppSettings.Get("DataProvider");
           return GetBase(provider);
       }

        internal static string Connected(EnumDataProvider dataProvider)
        {
            return GetBase(dataProvider.ToString());
        }

        private static string GetBase(string provider)
        {
            switch (provider.ToLower())
            {
                case "sql":
                    return "name=Sql";
                case "mysql":
                    return "name=MySql";
                default:
                    return "";
            }
        }
    }

Vamos a crear una clase que mapea un objeto y una tabla de una base de datos.


class MapperEngineering : EntityTypeConfiguration
    {
        public MapperEngineering()
        {
            ToTable("Engineering");

            HasKey(item => item.Id);
            Property(item => item.Id)
                .HasColumnName("Id")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                .IsRequired();

            Property(item => item.Name)
                .HasColumnName("Name")
                .HasMaxLength(255)
                .IsUnicode()
                .IsRequired();
        }
    }

Se crea el contexto de la base de datos

class DataBaseContext : DbContext
    {
        public DataBaseContext()
            : base(Connection.Connected()) { }

        public DataBaseContext(EnumDataProvider dataProvider) :
            base(Connection.Connected(dataProvider)) { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove();
            modelBuilder.Configurations.Add(new MapperEngineering());
            base.OnModelCreating(modelBuilder);
        }
    }

Ahora vamos a crear la interfaz y el patrón repositorio base

public interface IRepositoryGeneric where T : Entity
    {
        #region CRUD
        void Insert(T entidad);

        void Delete(T entidad);

        IEnumerable Find(Expression> expresion);

        T GetById(long id);

        IEnumerable FindAll();

        IEnumerable FindAll(Expression> orderbyExpression);

        void Saves(T entidad);
        #endregion

        #region Paged
        IEnumerable GetPage(bool desc, Expression> orderbyExpression, int currentPage,
            int pageSize, out int totalCount);

        IEnumerable GetPage(bool desc, Expression> orderbyExpression,
            Expression> expression, int currentPage, int pageSize, out int totalCount);
        #endregion

        #region Other

        decimal Sum(Expression> expression);

        bool Exist(Expression> expresion, out IEnumerable items);

        bool Exist(long id, out T item);
        #endregion
    }

public class Repository : IDisposable, IRepositoryGeneric where T : Entity
    {
        private readonly DbContext _contexto;
        private readonly DbSet _entities;
        private bool _disposed;

        public Repository(EnumDataProvider dataProvider)
        {
            _contexto = new DataBaseContext(dataProvider);
            _entities = _contexto.Set();
        }

        protected Repository()
        {
            _contexto = new DataBaseContext();
            _entities = _contexto.Set();
        }

        #region CRUD
        public void Insert(T entidad)
        {
            _entities.Add(entidad);
            _contexto.Entry(entidad).State = EntityState.Added;
        }

        public void Delete(T entidad)
        {
            _entities.Remove(entidad);
            _contexto.Entry(entidad).State = EntityState.Deleted;
        }

        public IEnumerable Find(Expression> expresion)
        {
            return _entities.Where(expresion);
        }

        public T GetById(long id)
        {
            return _entities.Find(id);
        }

        public IEnumerable FindAll()
        {
            return _entities;
        }

        public IEnumerable FindAll(Expression> orderbyExpression)
        {
            return _entities.OrderBy(orderbyExpression);
        }

        public void Saves(T entidad)
        {
            var entry = _contexto.Entry(entidad);
            entry.State = EntityState.Modified;
        }
        #endregion

        #region Paged
        public IEnumerable GetPage(bool desc, Expression> orderbyExpression, int currentPage,
            int pageSize, out int totalCount)
        {
            totalCount = _entities.Count();
            if (desc)
            {
                return
                    _entities.OrderByDescending(orderbyExpression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
            }

            return
                    _entities.OrderBy(orderbyExpression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
        }

        public IEnumerable GetPage(bool desc, Expression> orderbyExpression,
            Expression> expression, int currentPage, int pageSize, out int totalCount)
        {
            totalCount = _entities.Count(expression);

            if (desc)
            {
                return
                    _entities.Where(expression).OrderByDescending(expression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
            }

            return
                    _entities.Where(expression).OrderBy(expression)
                        .Skip((currentPage - 1) * pageSize)
                        .Take(pageSize);
        }

        #endregion

        #region Other

        public decimal Sum(Expression> expression)
        {
            return _entities.Sum(expression);
        }

        public bool Exist(Expression> expresion, out IEnumerable items)
        {
            items = Find(expresion);
            return items.Any();
        }
        public bool Exist(long id, out T item)
        {
            item = GetById(id);
            return item != null;
        }
        #endregion

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!_disposed)
                if (disposing)
                    _contexto.Dispose();
            _disposed = true;
        }
    }

 public class RepositoryEngineering: Repository
    {
        public RepositoryEngineering() { }

        public RepositoryEngineering(EnumDataProvider dataProvider) 
            : base(dataProvider) { }
    }

TEST

[TestMethod]
        public void SelectRepository()
        {
            var context = new RepositoryEngineering();
            var n = context.FindAll();

            Assert.AreEqual(n.Count(), 7);
        }

[TestMethod]
        public void InsertRepository()
        {
            var context = new RepositoryEngineering(EnumDataProvider.MySql);
            context.Insert(new Engineering { Name = "Engineering" });
        }
 
Saludos
 

No hay comentarios:

Publicar un comentario