zoukankan      html  css  js  c++  java
  • 【从零开始搭建自己的.NET Core Api框架】(六)泛型仓储的作用

    系列目录

    .  创建项目并集成swagger

      1.1 创建

      1.2 完善

    二. 搭建项目整体架构

    三. 集成轻量级ORM框架——SqlSugar

      3.1 搭建环境

      3.2 实战篇:利用SqlSugar快速实现CRUD

      3.3 生成实体类

    四. 集成JWT授权验证

    五. 实现CORS跨域

    六. 集成泛型仓储

     


     源码下载:https://github.com/WangRui321/RayPI_V2.0

    注:以下项目里的Service层其实是DAL层的意思,以前都习惯写DAL的,经园友回复提醒,Service一般指业务逻辑层,用Service确实不准确,下个版本更新会更正一下~

      1. 根

    之前在集成SqlSugar的时候,我们用Student类作为例子,写了5个基础的接口:获取集合、获取单个、添加、修改、删除,也就是常说的仓储的CRUD了。

    Service层的代码是这样的:

    而且我们规定,以后每个实体类都必须有这个5个基础接口。

    所以,当我们再添加一个实体(比如Teacher)时,在TeacherService中也要写和StudentService几乎一样的代码(其实就是把代码里所有“Student”换成“Teacher”就行了)。

    这么多重复代码,显然是不符合程序员的审美的。这个时候使用泛型仓储就再适合不过了。

      2. 道

    整体思路是,写一个基类“BaseService”,这个基类是一个抽象的泛型类,然后让每个实体的Service都继承它。

    那么当再新建一个Service时,不需要写任何代码,就已经实现了我们需要的那5种基础CRUD了。

     2.1 IService层

    在IService层新建一个IBase接口:

    using RayPI.Model;
    
    namespace RayPI.IService
    {
        public interface IBase<T> where T:class,new()
        {
            /// <summary>
            /// 获取分页列表
            /// </summary>
            /// <param name="pageIndex"></param>
            /// <param name="pageSize"></param>
            /// <returns></returns>
            TableModel<T> GetPageList(int pageIndex, int pageSize);
            /// <summary>
            /// 获取单个
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            T Get(long id);
            /// <summary>
            /// 添加
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            bool Add(T entity);
            /// <summary>
            /// 编辑
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            bool Update(T entity);
            /// <summary>
            /// 批量删除
            /// </summary>
            /// <param name="ids"></param>
            /// <returns></returns>
            bool Dels(dynamic[] ids);
        }
    }
    IBase

    该接口是个泛型接口,里面集成了对泛型T的5中基础CRUD操作。

     2.2 Service层

    在Service层新建一个BaseService类:

    using RayPI.Model;
    using SqlSugar;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    
    namespace RayPI.Service
    {
        /// <summary>
        /// 服务层基类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public abstract class BaseService<T> where T:class,new()
        {
            public BaseService()
            {
                db = GetClient();
                sdb = db.GetSimpleClient();
            }
            public SqlSugarClient db;
            public SimpleClient sdb;
            /// <summary>
            /// 获取客户端
            /// </summary>
            /// <returns></returns>
            private SqlSugarClient GetClient()
            {
                SqlSugarClient db = new SqlSugarClient(
                    new ConnectionConfig()
                    {
                        ConnectionString = BaseDBConfig.ConnectionString,
                        DbType = DbType.SqlServer,
                        IsAutoCloseConnection = true
                    }
                );
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    Console.WriteLine(sql + "
    " + db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
                    Console.WriteLine();
                };
                return db;
            }
    
            #region CRUD
            public TableModel<T> GetPageList(int pageIndex, int pageSize)
            {
                PageModel p = new PageModel() { PageIndex = pageIndex, PageSize = pageSize };
                Expression<Func<T, bool>> ex = (it => 1 == 1);
                List<T> data = sdb.GetPageList(ex, p);
                var t = new TableModel<T>
                {
                    Code = 0,
                    Count = p.PageCount,
                    Data = data,
                    Msg = "成功"
                };
                return t;
            }
    
            public T Get(long id)
            {
                return sdb.GetById<T>(id);
            }
    
            public bool Add(T entity)
            {
                return sdb.Insert(entity);
            }
    
            public bool Update(T entity)
            {
                return sdb.Update(entity);
            }
    
            public bool Dels(dynamic[] ids)
            {
                return sdb.DeleteByIds<T>(ids);
            }
            #endregion
        }
    }
    BaseService

    该类为abstract抽象类,只能用来被其他类继承,不能实例化。

    然后该类除了之前的获取SqlSugarClient的函数,还了5个集成基础CRUD操作,不一样的是这里不是传的实体类,而是一个泛型T。

      3. 果

    下面,我们写一个Teacher的完整的增删改查。

    先在数据库新建一张教师表:

    然后运行项目,调用我们之前写好的自动生成实体类的接口:

    生成的实体类是这样的:

     

    在IService层新建一个ITeacher接口:

    跟之前不一样的是,这个接口里不需要再写增删改查的接口了,直接继承IBase,把Teacher传过去,就行了。

    在Service层,新建一个TeacherService:

    该Service也不要写增删改查,直接继承BaseService就有了。

    然后Bussiness层和控制器层这里就不说了,跟之前一样:

    运行调试:

     这样,不用写任何底层仓储,就能实现基础的增删改查了,是不是很爽~

  • 相关阅读:
    IE7下元素的 'paddingtop' 遇到 'clear' 特性在某些情况下复制到 'paddingbottom'
    Foundation HTML5 Canvas中的2处错误
    近期学习技术安排
    2011年工作总结和展望(上篇)
    详解ObjectiveC消息传递机制
    ObjectiveC 2.0的运行时编程消息转发
    c# Pdf 转换图片
    c语言指针用法难点
    C# web实现word 转Html、office转Html、pdf转图片 在线预览文件
    ObjectiveC中什么是类
  • 原文地址:https://www.cnblogs.com/RayWang/p/9498591.html
Copyright © 2011-2022 走看看