none
Consulta con patron de especificaciones RRS feed

  • Pregunta

  • Hola Comunidad!

    Estoy trabajando en un proyecto de practica para aprender nuevas cosas y estoy implementando un Repositorio de datos generico publicado por Microsoft.

    Mi duda es la siguiente. Al usar un patron de repositorios pierdo el poder hacer querys en el DbContext?

        public class EntityRepositoryBase<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
        {
            private readonly SecurityDbContext _dbContext;
            private readonly ISecurityLogger<TEntity> _logger;
    
            public EntityRepositoryBase(SecurityDbContext dbContext, ISecurityLogger<TEntity> logger)
            {
                _dbContext = dbContext;
                _logger = logger;
            }
    
            public virtual async Task<TEntity> GetByCodeAsync(string code)
            {
                try
                {
                    return await _dbContext.Set<TEntity>().FindAsync(code);
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"{ex.Message}, {ex.InnerException.Message} {ex.StackTrace}");
                    throw new Exception(ex.StackTrace);
                }
            }
    
            public async Task<IReadOnlyList<TEntity>> ListAllAsync()
            {
                try
                {
                    return await _dbContext.Set<TEntity>().ToListAsync();
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"{ex.Message}, {ex.InnerException.Message} {ex.StackTrace}");
                    throw new Exception(ex.StackTrace);
                }
            }
    
            public async Task<IReadOnlyList<TEntity>> ListAsync(ISpecification<TEntity> spec)
            {
                try
                {
                    return await ApplySpecification(spec).ToListAsync();
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"{ex.Message}, {ex.InnerException.Message} {ex.StackTrace}");
                    throw new Exception(ex.StackTrace);
                }
            }
    
            public async Task<int> CountAsync(ISpecification<TEntity> spec)
            {
                try
                {
                    return await ApplySpecification(spec).CountAsync();
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"{ex.Message}, {ex.InnerException.Message} {ex.StackTrace}");
                    throw new Exception(ex.StackTrace);
                }
            }
    
            public async Task<bool> AddAsync(TEntity entity)
            {
                try
                {
                    _dbContext.Set<TEntity>().Add(entity);
                    return await _dbContext.SaveChangesAsync() > 0;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"{ex.Message}, {ex.InnerException.Message} {ex.StackTrace}");
                    throw new Exception(ex.StackTrace);
                }
            }
    
            public async Task<bool> UpdateAsync(TEntity entity)
            {
                try
                {
                    _dbContext.Entry(entity).State = EntityState.Modified;
                    return await _dbContext.SaveChangesAsync() > 0;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"{ex.Message}, {ex.InnerException.Message} {ex.StackTrace}");
                    throw new Exception(ex.StackTrace);
                }
            }
    
            public async Task<bool> DeleteAsync(TEntity entity)
            {
                try
                {
                    _dbContext.Set<TEntity>().Remove(entity);
                    return await _dbContext.SaveChangesAsync() > 0;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"{ex.Message}, {ex.InnerException.Message} {ex.StackTrace}");
                    throw new Exception(ex.StackTrace);
                }
            }
    
            private IQueryable<TEntity> ApplySpecification(ISpecification<TEntity> spec)
            {
                return SpecificationEvaluator<TEntity>.GetQuery(_dbContext.Set<TEntity>().AsQueryable(), spec);
            }
    
            #region Test Filter
            public virtual async Task<IReadOnlyList<TEntity>> GetAllAsync(Expression<Func<TEntity, bool>> filter, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, Func<IQueryable<TEntity>, IQueryable<TEntity>> includes = null)
            {
                var result = QueryDb(filter, orderBy, includes);
                return await result.ToListAsync();
            }
    
            protected IQueryable<TEntity> QueryDb(Expression<Func<TEntity, bool>> filter, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy, Func<IQueryable<TEntity>, IQueryable<TEntity>> includes)
            {
                IQueryable<TEntity> query = _dbContext.Set<TEntity>();
    
                if (filter != null)
                {
                    query = query.Where(filter);
                }
    
                if (includes != null)
                {
                    query = includes(query);
                }
    
                if (orderBy != null)
                {
                    query = orderBy(query);
                }
    
                return query;
            }
            #endregion
        }
    }

    Ejemplo como puede hacer un Where, Join, Select usando un patron de Repositorios Generico. O en este caso la forma de poder hacerlo es usando una Especificacion.

    lunes, 29 de julio de 2019 3:03

Respuestas

  • Hola

     para hacer busqueda parametrisadas ocupas incluir expression

    algo asi

     public virtual List<T> GetAll(params Expression<Func<T, object>>[] navigationProperties)
     {
         List<T> list = new List<T>();
         try
         {
             IQueryable<T> dbQuery = context.Set<T>();
             foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
             {
                 dbQuery = dbQuery.Include<T, object>(navigationProperty);
             }
    
             list = dbQuery.AsNoTracking().ToList<T>();
         }
         catch (Exception ex)
         {
             MessageBox.Show(ex.Message);         
         }
         return list;
     }
    
     public virtual List<T> GetList(Func<T, bool> where,
          params Expression<Func<T, object>>[] navigationProperties)
     {
         List<T> list = new List<T>();
         try
         {
             IQueryable<T> dbQuery = context.Set<T>();
             foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
             {
                 dbQuery = dbQuery.Include<T, object>(navigationProperty);
             }
             list = dbQuery.AsNoTracking().Where(where).ToList<T>();
         }
         catch (Exception ex)
         {
             MessageBox.Show(ex.Message);
        }
         return list;
     }
    
    y puedes usar lambda

    • Propuesto como respuesta Pablo RubioModerator miércoles, 31 de julio de 2019 16:43
    • Marcado como respuesta jose_boliv jueves, 8 de agosto de 2019 4:25
    lunes, 29 de julio de 2019 4:43