Home > Enterprise >  calling stored procedure using repository pattern generic repository
calling stored procedure using repository pattern generic repository

Time:10-29

I am using generic repo to communicate with db for generic opertions, i want to add a function to call stored procedure or query.

i am trying to implement multiple generic in the class, however when i call this code, it always returns Iqueryable of type T, however, i want to use multiple classes T,T1,T2

RepositoryBase class

 public abstract class RepositoryBase<T,T1> : IRepositoryBase<T,T1> where T : class where 
      T1:class
    {
        protected RepositoryContext RepositoryContext;
        protected DbSet<T> dbSet;
        public RepositoryBase(RepositoryContext repositoryContext)
        {
            RepositoryContext = repositoryContext;
        }

        public IQueryable<T> FindAll(bool trackChanges) => !trackChanges ?
             RepositoryContext.Set<T>()
             .AsNoTracking() :
             RepositoryContext.Set<T>();
        public IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression,
                bool trackChanges) =>
                !trackChanges ?
                RepositoryContext.Set<T>()
                .Where(expression)
                .AsNoTracking() :
                RepositoryContext.Set<T>()
                .Where(expression);
        public void Create(T entity) => RepositoryContext.Set<T>().Add(entity);
        public void Update(T entity) => RepositoryContext.Set<T>().Update(entity);
        public void Delete(T entity) => RepositoryContext.Set<T>().Remove(entity);

        //this is the function i am facing issue
        public IQueryable<T> ExecuteSqlQueryOrProcedure(string sql) 
        {
            return RepositoryContext.Set<T>().FromSqlRaw(sql);
        }
        
    }

IRepositoryBase interface

    {
        IQueryable<T> FindAll(bool trackChanges);
        IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression,
        bool trackChanges);
        void Create(T entity);
        void Update(T entity);
        void Delete(T entity);

        IQueryable<T> ExecuteSqlQueryOrProcedure(string sql);
        
    }

below is the repository class where i call repository base function..

public class SurveyDashboardRepository : RepositoryBase<SurveyStatistics, SurveyCropTypeWise>, ISurveyDashboardRepository
        {
            public SurveyDashboardRepository(RepositoryContext repositoryContext) : base(repositoryContext)
            {
    
            }
    
            public async Task<IList<SurveyStatistics>> StatisticsAsync(SurveyStatisticsDto dto)
            {
                var query = $"Exec CN_RPT_SurveyDashBoard @Flag='GTY',@ForTheYear={dto.ForTheYear}";
                if (dto.PlantCode.HasValue)
                {
                    query  = $",@PlantCode={dto.PlantCode}";
                }
    
                return await ExecuteSqlQueryOrProcedure(query).ToListAsync();
            }
    
    
            public async Task<IList<SurveyCropTypeWise>> CropTypeWiseAsync(SurveyCropTypeWiseDto dto)
            {
                var query = $"Exec CN_RPT_SurveyDashBoard @Flag='CT',@ForTheYear={dto.ForTheYear}";
                if (dto.PlantCode.HasValue)
                {
                    query  = $",@PlantCode={dto.PlantCode}";
                }
                //on this line i am getting error 
                return await ExecuteSqlQueryOrProcedure<SurveyCropTypeWise>(query).ToList<SurveyCropTypeWise>();
            }
    
            
        }

below is the related interface to above repository class

public interface ISurveyDashboardRepository
        {
            Task<IList<SurveyStatistics>> StatisticsAsync(SurveyStatisticsDto dto);
            Task<IList<SurveyCropTypeWise>> CropTypeWiseAsync(SurveyCropTypeWiseDto dto);
    
        }

so in each repository i am going to call several procedures, i am not sure how to handle this issue,any help is really appreciated.

CodePudding user response:

You try to make the generic repository do too much. The only reason to use it, in this case, is to get a base class that can handle the CRUD operations.

In regards to IQueryable it's a leaky abstraction, as it forces persistent specific knowledge upon the caller and violates law of Demeter. It's therefore not a complete abstraction. Remove it if you truly want to follow the repository pattern.

Once those things are done your base classes are much simpler and you will not have a problem with managing multiple types.

If you still have trouble with multiple type definitions, stop using the base class for that repository. Nothing says that all repositories in a project need to follow the exact same pattern. Apply it where it fits, or it worsen your code base.

  • Related