一. 结构介绍

1. 分层建项目

 新建:YpfCore.AdminWeb、YpfCore.Data、YpfCore.DTO、YpfCore.IService、YpfCore.Service、YpfCore.Utils,每层的作用如下:

 A. YpfCore.AdminWeb层:UI层,存放一些页面和进行一些基本的业务逻辑,供客户端调用。

 B. YpfCore.Data层:数据层,存放数据库实体映射类和相关配置类、EF上下文类。

 C. YpfCore.DTO层:数据传输对象层,存放一些业务逻辑实体,供UI层调用。

 D. YpfCore.IService层:业务接口层。

 E. YpfCore.Service层:业务层。

 F. YpfCore.Utils层:帮助类层

(后续补充 YpfCore.WebApi层,用于前后端分离的接口编写)。

2. 项目结构图

第一节:框架基础架构构建(CoreMvc+EFCore+AutoFac)

 

二. 搭建步骤

1.  数据层构建

 (1).通过Nuget给YpfCore.Data层安装EFCore相关的程序集,如下:

  【Microsoft.EntityFrameworkCore】【Microsoft.EntityFrameworkCore.SqlServer】【Microsoft.EntityFrameworkCore.Design】【Microsoft.EntityFrameworkCore.Tools】        

PS: 这里安装的是 3.1.8 版本,此处搭建适宜SQLServer为例演示,MySQL相关集成后续扩展封装章节会体现。

 (2).通过下面指令映射数据库实体文件,这里采用注解即DataAnnotations进行关系格式映射。

  【Scaffold-DbContext "Server=47.92.xxx.xxx;Database=CoreFrameDB;User ID=CoreFrameDB;Password=123456;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Entity -Context CoreFrameDBContext -UseDatabaseNames -DataAnnotations】

 (3). 为了便于后续业务代码的编写,这里我们添加日志,用于打印Linq 转变成的 SQL语句。

 通过Nuget安装日志程序集:【Microsoft.Extensions.Logging】【Microsoft.Extensions.Logging.Debug】,修改EFCore上下问中的代码如下:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
   optionsBuilder.UseLoggerFactory(LoggerFactory.Create(build =>
   {
       build.AddDebug();
   }));
}

2. 业务接口层构建

 (1). 给YpfCore.IService层添加对YpfCore.Data层的引用,同时通过Nuget安装如下程序集:

 【Microsoft.EntityFrameworkCore】【System.Data.SqlClient】

 (2). 新增IBaseService 和 ISupport接口,IBaseService用于定义EFCore上下文对DB操作的方法约束,ISupport为了标记后续哪些子类Service可以被注入到YpfCore.AdminWeb层。

IBaseService代码分享

 public interface IBaseService
    {
        /****************************************下面进行方法的封装(同步)***********************************************/
        //1. 直接提交数据库

        #region 01-数据源
        IQueryable<T> Entities<T>() where T : class;

        IQueryable<T> EntitiesNoTrack<T>() where T : class;

        #endregion

        #region 02-新增
        int Add<T>(T model) where T : class;

        #endregion

        #region 03-删除
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="model">需要删除的实体</param>
        /// <returns></returns>
        int Del<T>(T model) where T : class;

        #endregion

        #region 04-根据条件删除(支持批量删除)
        /// <summary>
        /// 根据条件删除(支持批量删除)
        /// </summary>
        /// <param name="delWhere">传入Lambda表达式(生成表达式目录树)</param>
        /// <returns></returns>
        int DelBy<T>(Expression<Func<T, bool>> delWhere) where T : class;

        #endregion

        #region 05-单实体修改
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="model">修改后的实体</param>
        /// <returns></returns>
        int Modify<T>(T model) where T : class;

        #endregion

        #region 06-批量修改(非lambda)
        /// <summary>
        /// 批量修改(非lambda)
        /// </summary>
        /// <param name="model">要修改实体中 修改后的属性 </param>
        /// <param name="whereLambda">查询实体的条件</param>
        /// <param name="proNames">lambda的形式表示要修改的实体属性名</param>
        /// <returns></returns>
        int ModifyBy<T>(T model, Expression<Func<T, bool>> whereLambda, params string[] proNames) where T : class;

        #endregion

        #region 07-根据条件查询
        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="whereLambda">查询条件(lambda表达式的形式生成表达式目录树)</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        List<T> GetListBy<T>(Expression<Func<T, bool>> whereLambda, bool isTrack = true) where T : class;

        #endregion

        #region 08-根据条件排序和查询
        /// <summary>
        /// 根据条件排序和查询
        /// </summary>
        /// <typeparam name="Tkey">排序字段类型</typeparam>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda">排序条件</param>
        /// <param name="isAsc">升序or降序</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        List<T> GetListBy<T, Tkey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true, bool isTrack = true) where T : class;

        #endregion

        #region 09-分页查询(根据Lambda排序)
        /// <summary>
        /// 根据条件排序和查询
        /// </summary>
        /// <typeparam name="Tkey">排序字段类型</typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda">排序条件</param>
        /// <param name="isAsc">升序or降序</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        List<T> GetPageList<T, Tkey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true, bool isTrack = true) where T : class;

        #endregion

        #region 10-分页查询(根据名称排序)
        /// <summary>
        /// 分页查询输出总行数(根据名称排序)
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="rowCount">输出的总数量</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="sortName">排序名称</param>
        /// <param name="sortDirection">asc 或 desc</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        List<T> GetPageListByName<T>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, string sortName, string sortDirection, bool isTrack = true) where T : class;

        #endregion

        #region 11-分页查询输出总行数(根据Lambda排序)
        /// <summary>
        /// 根据条件排序和查询
        /// </summary>
        /// <typeparam name="Tkey">排序字段类型</typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda">排序条件</param>
        /// <param name="isAsc">升序or降序</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        List<T> GetPageList<T, Tkey>(int pageIndex, int pageSize, out int rowCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true, bool isTrack = true) where T : class;

        #endregion

        #region 12-分页查询输出总行数(根据名称排序)
        /// <summary>
        /// 分页查询输出总行数(根据名称排序)
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="rowCount">输出的总数量</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="sortName">排序名称</param>
        /// <param name="sortDirection">asc 或 desc</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        List<T> GetPageListByName<T>(int pageIndex, int pageSize, out int rowCount, Expression<Func<T, bool>> whereLambda, string sortName, string sortDirection, bool isTrack = true) where T : class;

        #endregion





        //2. SaveChange剥离出来,处理事务

        #region 01-批量处理SaveChange()
        /// <summary>
        /// 事务批量处理
        /// </summary>
        /// <returns></returns>
        int SaveChange();

        #endregion

        #region 02-新增
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="model">需要新增的实体</param>
        void AddNo<T>(T model) where T : class;

        #endregion

        #region 03-删除
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="model">需要删除的实体</param>
        void DelNo<T>(T model) where T : class;

        #endregion

        #region 04-根据条件删除
        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="delWhere">需要删除的条件</param>
        void DelByNo<T>(Expression<Func<T, bool>> delWhere) where T : class;

        #endregion

        #region 05-修改
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="model">修改后的实体</param>
        void ModifyNo<T>(T model) where T : class;

        #endregion


        //3. EF调用sql语句

        #region 01-执行增加,删除,修改操作(或调用存储过程)
        /// <summary>
        /// 执行增加,删除,修改操作(或调用存储过程)
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="pars"></param>
        /// <returns></returns>
        int ExecuteSql(string sql, params SqlParameter[] pars);


        #endregion

        #region 02-执行查询操作
        /// <summary>
        /// 执行查询操作
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="pars"></param>
        /// <returns></returns>
        List<T> ExecuteQuery<T>(string sql, bool isTrack = true, params SqlParameter[] pars) where T : class;

        #endregion

        #region 03-执行查询操作(与Linq相结合)
        /// <summary>
        /// 执行查询操作
        /// 注:查询必须返回实体的所有属性字段;结果集中列名必须与属性映射的项目匹配;查询中不能包含关联数据
        /// 除Select以外其他的SQL语句无法执行
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        ///  <param name="whereLambda">查询条件</param>
        /// <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <param name="pars"></param>
        /// <returns></returns>
        List<T> ExecuteQueryWhere<T>(string sql, Expression<Func<T, bool>> whereLambda, bool isTrack = true, params SqlParameter[] pars) where T : class;

        #endregion



        /****************************************下面进行方法的封装(异步)***********************************************/
        //1. 直接提交数据库

        #region 01-新增
        Task<int> AddAsync<T>(T model) where T : class;

        #endregion

        #region 02-删除
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="model">需要删除的实体</param>
        /// <returns></returns>
        Task<int> DelAsync<T>(T model) where T : class;

        #endregion

        #region 03-根据条件删除(支持批量删除)
        /// <summary>
        /// 根据条件删除(支持批量删除)
        /// </summary>
        /// <param name="delWhere">传入Lambda表达式(生成表达式目录树)</param>
        /// <returns></returns>
        Task<int> DelByAsync<T>(Expression<Func<T, bool>> delWhere) where T : class;

        #endregion

        #region 04-单实体修改
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="model">修改后的实体</param>
        /// <returns></returns>
        Task<int> ModifyAsync<T>(T model) where T : class;

        #endregion

        #region 05-批量修改(非lambda)
        /// <summary>
        /// 批量修改(非lambda)
        /// </summary>
        /// <param name="model">要修改实体中 修改后的属性 </param>
        /// <param name="whereLambda">查询实体的条件</param>
        /// <param name="proNames">lambda的形式表示要修改的实体属性名</param>
        /// <returns></returns>
        Task<int> ModifyByAsync<T>(T model, Expression<Func<T, bool>> whereLambda, params string[] proNames) where T : class;

        #endregion

        #region 06-根据条件查询
        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <param name="whereLambda">查询条件(lambda表达式的形式生成表达式目录树)</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        Task<List<T>> GetListByAsync<T>(Expression<Func<T, bool>> whereLambda, bool isTrack = true) where T : class;

        #endregion

        #region 07-根据条件排序和查询
        /// <summary>
        /// 根据条件排序和查询
        /// </summary>
        /// <typeparam name="Tkey">排序字段类型</typeparam>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda">排序条件</param>
        /// <param name="isAsc">升序or降序</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        Task<List<T>> GetListByAsync<T, Tkey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true, bool isTrack = true) where T : class;

        #endregion

        #region 08-分页查询(根据Lambda排序)
        /// <summary>
        /// 根据条件排序和查询
        /// </summary>
        /// <typeparam name="Tkey">排序字段类型</typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页容量</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda">排序条件</param>
        /// <param name="isAsc">升序or降序</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        Task<List<T>> GetPageListAsync<T, Tkey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true, bool isTrack = true) where T : class;

        #endregion

        #region 09-分页查询(根据名称排序)
        /// <summary>
        /// 分页查询输出总行数(根据名称排序)
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="rowCount">输出的总数量</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="sortName">排序名称</param>
        /// <param name="sortDirection">asc 或 desc</param>
        ///  <param name="isTrack">是否跟踪状态,默认是跟踪的</param>
        /// <returns></returns>
        Task<List<T>> GetPageListByNameAsync<T>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, string sortName, string sortDirection, bool isTrack = true) where T : class;

        #endregion




        //2. SaveChange剥离出来,处理事务

        #region 01-批量处理SaveChange()
        /// <summary>
        /// 事务批量处理
        /// </summary>
        /// <returns></returns>
        Task<int> SaveChangeAsync();

        #endregion

        #region 02-新增
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="model">需要新增的实体</param>
        Task<EntityEntry<T>> AddNoAsync<T>(T model) where T : class;

        #endregion

        #region 03-根据条件删除
        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="delWhere">需要删除的条件</param>
        Task DelByNoAsync<T>(Expression<Func<T, bool>> delWhere) where T : class;

        #endregion


        //3. EF调用sql语句

        #region 01-执行增加,删除,修改操作(或调用存储过程)
        /// <summary>
        /// 执行增加,删除,修改操作(或调用存储过程)
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="pars"></param>
        /// <returns></returns>
        Task<int> ExecuteSqlAsync(string sql, params SqlParameter[] pars);


        #endregion


    }
View Code

相关文章: