【问题标题】:calling stored procedure using repository pattern generic repository使用存储库模式通用存储库调用存储过程
【发布时间】:2021-10-21 08:01:19
【问题描述】:

我正在使用通用 repo 与 db 进行通用操作通信,我想添加一个函数来调用存储过程或查询。

我正在尝试在类中实现多个泛型,但是当我调用此代码时,它总是返回 T 类型的 Iqueryable,但是,我想使用多个类 T、T1、T2

RepositoryBase

 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接口

    {
        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);
        
    }

下面是我调用存储库基函数的存储库类..

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>();
            }
    
            
        }

下面是上面repository类的相关接口

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

所以在每个存储库中我将调用几个程序,我不确定如何处理这个问题,非常感谢任何帮助。

【问题讨论】:

    标签: generics asp.net-core-webapi repository-pattern


    【解决方案1】:

    您试图让通用存储库做得太多。在这种情况下,使用它的唯一原因是获得一个可以处理 CRUD 操作的基类。

    关于IQueryable,它是一个泄漏的抽象,因为它强制调用者持久的特定知识并且违反了得墨忒耳法则。因此,它不是一个完整的抽象。如果您真的想遵循存储库模式,请将其删除。

    一旦完成这些事情,您的基类就会简单得多,管理多种类型也不会有问题。

    如果您仍然遇到多个类型定义的问题,请停止使用该存储库的基类。没有什么说项目中的所有存储库都需要遵循完全相同的模式。在合适的地方应用它,否则会恶化你的代码库。

    【讨论】:

    • 所以你的意思是,我应该移动这个过程函数 public IQueryable ExecuteSqlQueryOrProcedure(string sql) { return RepositoryContext.Set().FromSqlRaw(sql); } 到其他一些静态类,那么我应该直接在我的域存储库中使用这个静态函数。
    • 公共 api 中根本不应该有 IQueryable。
    • ``` 公共异步任务 StatisticsAsync(SurveyStatisticsDto dto) { var query = $"Exec CN_RPT_SurveyDashBoard @Flag='GTY',@ForTheYear={dto.ForTheYear}"; if (dto.PlantCode.HasValue) { query += $",@PlantCode={dto.PlantCode}"; } 返回等待 _repositoryContext.Set().FromSqlRaw(query); ```所以这里无法得到结果,我也尝试了 firstOrDefaut
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多