NET7下EFCORE的通用增删查改类

发布时间 2023-07-27 21:44:29作者: 牛腩
NET7下EFCORE的通用增删查改类
代码摘录自《深入浅出ASP.NET CORE》
 
    /// <summary>
    /// 所有仓储的约定,此接口仅作为约定,用于标识他们
    /// </summary>
    /// <typeparam name="TEntity">传入仓储的实体模型</typeparam>
    /// <typeparam name="TPrimaryKey">传入仓储的主键类型</typeparam>
    public interface IRepository<TEntity,TPrimaryKey> where TEntity : class
    {
        #region 查询
        IQueryable<TEntity> GetAll();
        List<TEntity> GetAllList();
        Task<List<TEntity>> GetAllListAsync();
        List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate);
        Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate);
        TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate);
        Task<TEntity> FirstOrDefaultAsycn(Expression<Func<TEntity, bool>> predicate);
        #endregion

        #region 新增
        TEntity Insert(TEntity entity);
        Task<TEntity> InsertAsync(TEntity entity);
        #endregion

        #region 更新
        TEntity Update(TEntity entity);
        Task<TEntity> UpdateAsync(TEntity entity);
        #endregion

        #region 删除
        void Delete(TEntity entity);
        Task DeleteAsync(TEntity entity);
        void Delete(Expression<Func<TEntity, bool>> predicate);
        Task DeleteAsync(Expression<Func<TEntity, bool>> predicate);
        #endregion

        #region 总和计算
        int Count();
        Task<int> CountAsync();
        int Count(Expression<Func<TEntity, bool>> predicate);
        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate);
        #endregion
    }

  

    /// <summary>
    /// 默认仓储的通用功能实现,用于所有的领域模型
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TPrimaryKey"></typeparam>
    public class RepositoryBase<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey> where TEntity : class
    {
        protected readonly AppDbContext _appDbContext;

        public RepositoryBase(AppDbContext appDbContext)
        {
            _appDbContext = appDbContext;
        }

        public virtual DbSet<TEntity> Table=>_appDbContext.Set<TEntity>();

        public int Count()
        {
            return GetAll().Count();
        }

        public int Count(Expression<Func<TEntity, bool>> predicate)
        {
          return GetAll().Where(predicate).Count();
        }

        public async Task<int> CountAsync()
        {
           return await GetAll().CountAsync();
        }

        public async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate)
        {
           return await GetAll().Where(predicate).CountAsync();
        }

        public void Delete(TEntity entity)
        {
            AttachIfNot(entity);
            Table.Remove(entity);
            Save();
        }

        public async Task DeleteAsync(TEntity entity)
        {
            AttachIfNot(entity);
            Table.Remove(entity);
            await SaveAsync();
        }

        public void Delete(Expression<Func<TEntity, bool>> predicate)
        {
            foreach (var entity in GetAll().Where(predicate).ToList())
            {
                Delete(entity);
            }
        }

        public async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate)
        {
            foreach (var entity in GetAll().Where(predicate).ToList())
            {
              await  DeleteAsync(entity);
            }
        }

        public TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate)
        {
           return GetAll().FirstOrDefault(predicate);
        }

        public async Task<TEntity> FirstOrDefaultAsycn(Expression<Func<TEntity, bool>> predicate)
        {
           return await GetAll().FirstOrDefaultAsync(predicate);
        }

        public IQueryable<TEntity> GetAll()
        {
            return Table.AsQueryable();
        }

        public List<TEntity> GetAllList()
        {
           return GetAll().ToList();
        }

        public List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate)
        {
            return GetAll().Where(predicate).ToList();
        }

        public async Task<List<TEntity>> GetAllListAsync()
        {
           return await GetAll().ToListAsync();
        }

        public async Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate)
        {
           return await GetAll().Where(predicate).ToListAsync();
        }

        public TEntity Insert(TEntity entity)
        {
            var newEntity = Table.Add(entity).Entity;
            Save();
            return newEntity;
        }

        protected void Save()
        {
           _appDbContext.SaveChanges();
        }

        protected async Task SaveAsync() { 
            await _appDbContext.SaveChangesAsync();
        }
        /// <summary>
        /// 检查实体是否处于跟踪状态,如果是,则返回,如果不是,则添加跟踪状态
        /// </summary>
        /// <param name="entity"></param>
        protected virtual void AttachIfNot(TEntity entity) {
            var entry = _appDbContext.ChangeTracker.Entries().FirstOrDefault(e => e.Entity == entity);
            if (entry != null) { return; }
            Table.Attach(entity);
        }

        public async Task<TEntity> InsertAsync(TEntity entity)
        {
            var entityEntry = await Table.AddAsync(entity);
            await SaveAsync();
            return entityEntry.Entity;
        }

        public TEntity Update(TEntity entity)
        {
           AttachIfNot(entity);
            _appDbContext.Entry(entity).State = EntityState.Modified;
            Save();
            return entity;
        }

        public async Task<TEntity> UpdateAsync(TEntity entity)
        {
            AttachIfNot(entity);
            _appDbContext.Entry(entity).State = EntityState.Modified;
            await SaveAsync();
            return entity;
        }

   
    }

  

//假设有一学生接口需要有额外的登录接口,可新建一个IStudent接口,继承后只用加Login接口就行
    public interface IStudentRepository :IRepository<Student, int>
    {
        bool Login(string username, string password);
    }
    
//实现类除了要实现上面的接口,还要继承基类RepositoryBase
    public class StudentRepository : RepositoryBase<Student, int>, IStudentRepository
    {
        public StudentRepository(AppDbContext appDbContext) : base(appDbContext)
        {
        }

        public bool Login(string username, string password)
        {
            bool b = false;
            //GetAll是基类中的方法,返回 iquerable
            b = GetAll().Where(a=>a.username=username && a.password=password).Count()>0
            return b;    
        }
    }

  

//使用记得注入
  services.AddTransient(typeof(IRepository<,>), typeof(RepositoryBase<,>));
 services.AddTransient<IStudentRepository, StudentRepository>();

//控制器里的代码
private readonly IRepository<Student, int> _studentRepository;
private readonly IStudentRepository _studentRepository2;
 public WelcomeController(  IRepository<Student, int> studentRepository, IStudentRepository studentRepository2 )
        { 
            _studentRepository = studentRepository; 
            _studentRepository2 = studentRepository2;
        }
        public async Task<IActionResult> Index()
        {
 

            //_studentRepository2换成_studentRepository也成,只是没有Login方法
            Models.Student student =  await _studentRepository2.GetAll().FirstOrDefaultAsync();
            int count = await _studentRepository2.CountAsync();
            bool b = _studentRepository2.Login("niunan","123456");
            string str = $"取出一个学生:{student.Name},学生总数:{count}, 执行login方法结果:{false}";

            return Content($"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><div>原文:{src}</div><div>加密后:{jiami}</div><div>解密后:{jiemi}</div><div>{str}</div>","text/html");
        }