从壹开始先后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之七 || API项目总体搭建 6.2 轻量级ORM

本文3.0版本文章

本文涉及的内容,一样适用于3.0版本,不用修改。html

 

前言

一、在使用的时候,特别是更新数据的时候,若是不知道哪里有问题,能够查看数据库 和 实体类 的字段,是否大小写一致,好比 name 和 Name前端

二、在使用Sqlsugar 的 CodeFirst的时候,记得要先重建一个空的数据库,否则会提示错误。git

注意:Sqlsugar 5.x 版本已经支持自动建立数据库了,若是你用了最新的版本,能够不用手动建立(加上一行代码 db.DbMaintenance.CreateDatabase(); ,反之须要;github

 

三、要学会使用数据库监控分析器面试

 

 

  书接上文:《从壹开始先后端分离【 .NET Core2.0 Api + Vue 2.0 + AOP + 分布式】框架之六 || API项目总体搭建 6.1 仓储》,咱们简单的对总体项目进行搭建,用到了项目中常见的仓储模式+面向接口编程,核心的一共是六层,固然你也能够根据本身的需求进行扩展,好比我在其余的项目中会用到Common层,固然咱们这个项目接下来也会有,或者我还会添加Task层,主要是做为定时项目使用,我以前用的是Task Schedule,基本能知足需求。sql

 

  在上一节中,咱们最后提出了两个问题,不知道你们是否还记得,这里还从新说明一下:数据库

一、若是每一个仓储文件都须要把一个一个写出来,至少是四遍,会不会太麻烦,并且没法复用,失去了面向接口编程的意义;编程

二、每次接口调用的时候,须要引入不少命名空间,好比Blog.Core.IServices;Blog.Core.Services;Blog.Core.Repository等等后端

  对就是这两个问题,相信聪明的你们也都能看懂,或许还能给出相应的解决办法,好比泛型仓储,好比依赖注入,固然,若是你有更好的办法,欢迎留言,我会把你的想法写下了,让你们一块儿进步。这里先简单说下问题1中为何要四遍,仓储模式的基本就是如何将持久化动做和对象获取方式以及领域模型Domain Model结合起来,进一步:如何更加统一咱们的语言(Ubiquitous Language),一个整合持久化技术的好办法是仓储Repositories。明白了这个问题,你就知道,定义仓储,首先须要定义IRepository接口(1),而后再Repository中实现(2),接着在IService层中引用这些接口,同时也能够自定义扩展业务逻辑接口(3),最后在Service层中去实现(4),这就是四层。api

  问题明白了,咱们就要动手作起来,思考了下,若是干巴巴直接写泛型仓储,会比较干涩,因此我考虑今天先把数据持久化作出来,一个轻量级的ORM框架——SqlSugar。

 

零、今天完成的蓝色部分

 

 

0、建立实体模型与数据库

 

一、实体模型

在上篇文章中,咱们说到了仓储模式,所谓仓储,就是对数据的管理,所以,咱们就必需要有实体模型,下文说到了 Advertisement ,那就先建立它的实体模型,其余的相关模型,你们自行下载代码便可:

   public class Advertisement 
    {
        /// <summary>
        /// ID
        /// </summary>public int Id { get; set; }

        /// <summary>
        /// 广告图片
        /// </summary>public string ImgUrl { get; set; }

        /// <summary>
        /// 广告标题
        /// </summary>public string Title { get; set; }

        /// <summary>
        /// 广告连接
        /// </summary>public string Url { get; set; }

        /// <summary>
        /// 备注
        /// </summary>public string Remark { get; set; }

        /// <summary>
        /// 建立时间
        /// </summary>
        public DateTime Createdate { get; set; } = DateTime.Now;
    }

 

二、建立数据库

既然要操做数据库,确定得先有一个数据库,这里提供了两种方式:

一、Sql语句生成(目前已经不更新,若是必定想要,去群文件下载)

二、经过个人项目,code first 生成,而且里边能够直接 seed data,这样就能生成一个完整的带数据的Database。

具体如何操做能够查看文章——《支持多种数据库 & 快速数据库生成》,若是你感受麻烦,就本身根据上边的实体模型,本身建立一个数据库。

 

 

1、在 IRepository 层设计接口

  还记得昨天咱们实现的Sum接口么,今天在仓储接口 IAdvertisementRepository.cs 添加CURD四个接口,首先须要将Model层添加引用,这个应该都会,之后再也不细说,以下:

 

namespace Blog.Core.IRepository
{
    public interface IAdvertisementRepository
    {
        int Sum(int i, int j);

        int Add(Advertisement model);
        bool Delete(Advertisement model);
        bool Update(Advertisement model);
        List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression);

    }
}

编译项目,提示错误,别慌!很正常,由于咱们如今只是添加了接口,尚未实现接口。

 

2、在 Repository 层实现相应接口

固然,咱们仍是在AdvertisementRepository.cs文件中操做,这里我有一个小技巧,不知道你们是否用到过,由于我比较喜欢写接口,这样不只能够不暴露核心代码,并且也可让用户调用的时候,直接看到简单的接口方法列表,而不去管具体的实现过程,这样的设计思路仍是比较提倡的,以下图:

 

 你先看到了继承的接口有红色的波浪线,证实有错误,而后右键该接口,点击 Quick Actions and Refactorings...,也就是 快速操做和重构 ,你就会看到VS的智能提示,双击左侧的Implement interface,也就是实现接口,以下图:

Visual Studio真是宇宙第一IDE,没的说 [手动点赞],而后就建立成功了,你就能够去掉throw处理,自定义代码编写了,固然,若是你不习惯或者惧怕出错,那就手动写吧,也是很快的。

namespace Blog.Core.Repository
{
    public class AdvertisementRepository : IAdvertisementRepository
    {
        public int Add(Advertisement model)
        {
            throw new NotImplementedException();
        }

        public bool Delete(Advertisement model)
        {
            throw new NotImplementedException();
        }

        public List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression)
        {
            throw new NotImplementedException();
        }

        public int Sum(int i, int j)
        {
            return i + j;
        }

        public bool Update(Advertisement model)
        {
            throw new NotImplementedException();
        }
    }
}

这个时候咱们从新编译项目,嗯!意料之中,没有错误,可是具体的数据持久化如何写呢?

 

3、引用轻量级的ORM框架——SqlSugar

首先什么是ORM, 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是经过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。这些概念我就不细说了,自从开发这些年,一直在讨论的问题就是用ADO.NET仍是用ORM框架,还记得前几年面试的时候,有一个经理问:

若是一个项目,你是用三层架构ADO,仍是用ORM中的EF?

 你们能够自由留言,我表示各有千秋吧,一个产品的存在即有合理性,我平时项目中也有ADO,也有EF,不过本系列教程中基于面向对象思想,面向接口思想,固然还有之后的面向切面编程(AOP),仍是使用ORM框架,不过是一个轻量级的,EF比较重,我在我其余的项目中用到了.Net MVC 6.0 + EF Code First 的项目,若是你们须要,我也开源出去,放在Github上,请文末留言吧~

  关于ORM有一些常见的框架,如SqlSugar、Dapper、EF、NHeberneit等等,这些我都或多或少的了解过,使用过,至于你要问我为啥用SqlSugar,只要一个缘由,做者是中国人,嗯!没错,这里给他打个广告,本系列中的前端框架Vue,也是咱们中国的,Vue做者尤雨溪,这里也祝福你们都能有本身的成绩,为国人争光!

扯远了,开始动手引入框架:

开始,咱们须要先向 Repository 层中引入SqlSugar,以下:

1)直接在类库中经过Nuget引入 sqlSugarCore,必定是Core版本的!,我我的采用这个办法,由于项目已经比较成型

2)Github下载源码,而后项目引用(点击跳转到Github下载页)

注意:为何要单独在仓储层来引入ORM持久化接口,是由于,下降耦合,若是之后想要换成EF或者Deper,只须要修改Repository就好了,其余都不须要修改,达到很好的解耦效果

 

编译一切正常,继续

首先呢,你须要了解下sqlsugar的具体使用方法,http://www.codeisbug.com/Doc/8,你先本身在控制台能够简单试一试,这里就不细说了,若是你们有须要,我能够单开一个文章,重点讲解SqlSugar这一块。

一、在Blog.Core.Repository新建一个sugar文件夹,而后添加两个配置文件,BaseDBConfig.cs 和  DbContext.cs ,这个你若是看了上边的文档,那这两个应该就不是问题。

namespace Blog.Core.Repository
{
    public class BaseDBConfig
    {
        public static string ConnectionString = File.ReadAllText(@"D:\my-file\dbCountPsw1.txt").Trim();

        //正常格式是

        //public static string ConnectionString = "server=.;uid=sa;pwd=sa;database=BlogDB"; 

        //原谅我用配置文件的形式,由于我直接调用的是个人服务器帐号和密码,安全起见

    }
}

 

 //DbContext.cs,一个详细的上下文类,看不懂不要紧,之后我会详细讲解

namespace Blog.Core.Repository
{
    public class DbContext
    {

        private static string _connectionString;
        private static DbType _dbType;
        private SqlSugarClient _db;

        /// <summary>
        /// 链接字符串 
        /// Blog.Core
        /// </summary>
        public static string ConnectionString
        {
            get { return _connectionString; }
            set { _connectionString = value; }
        }
        /// <summary>
        /// 数据库类型 
        /// Blog.Core 
        /// </summary>
        public static DbType DbType
        {
            get { return _dbType; }
            set { _dbType = value; }
        }
        /// <summary>
        /// 数据链接对象 
        /// Blog.Core 
        /// </summary>
        public SqlSugarClient Db
        {
            get { return _db; }
            private set { _db = value; }
        }

        /// <summary>
        /// 数据库上下文实例(自动关闭链接)
        /// Blog.Core 
        /// </summary>
        public static DbContext Context
        {
            get
            {
                return new DbContext();
            }

        }


        /// <summary>
        /// 功能描述:构造函数
        /// 做  者:Blog.Core
        /// </summary>
        private DbContext()
        {
            if (string.IsNullOrEmpty(_connectionString))
                throw new ArgumentNullException("数据库链接字符串为空");
            _db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = _connectionString,
                DbType = _dbType,
                IsAutoCloseConnection = true,
                IsShardSameThread = true,
                ConfigureExternalServices = new ConfigureExternalServices()
                {
                    //DataInfoCacheService = new HttpRuntimeCache()
                },
                MoreSettings = new ConnMoreSettings()
                {
                    //IsWithNoLockQuery = true,
                    IsAutoRemoveDataCache = true
                }
            });
        }

        /// <summary>
        /// 功能描述:构造函数
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="blnIsAutoCloseConnection">是否自动关闭链接</param>
        private DbContext(bool blnIsAutoCloseConnection)
        {
            if (string.IsNullOrEmpty(_connectionString))
                throw new ArgumentNullException("数据库链接字符串为空");
            _db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = _connectionString,
                DbType = _dbType,
                IsAutoCloseConnection = blnIsAutoCloseConnection,
                IsShardSameThread = true,
                ConfigureExternalServices = new ConfigureExternalServices()
                {
                    //DataInfoCacheService = new HttpRuntimeCache()
                },
                MoreSettings = new ConnMoreSettings()
                {
                    //IsWithNoLockQuery = true,
                    IsAutoRemoveDataCache = true
                }
            });
        }

        #region 实例方法
        /// <summary>
        /// 功能描述:获取数据库处理对象
        /// 做  者:Blog.Core
        /// </summary>
        /// <returns>返回值</returns>
        public SimpleClient<T> GetEntityDB<T>() where T : class, new()
        {
            return new SimpleClient<T>(_db);
        }
        /// <summary>
        /// 功能描述:获取数据库处理对象
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="db">db</param>
        /// <returns>返回值</returns>
        public SimpleClient<T> GetEntityDB<T>(SqlSugarClient db) where T : class, new()
        {
            return new SimpleClient<T>(db);
        }

        #region 根据数据库表生产实体类
        /// <summary>
        /// 功能描述:根据数据库表生产实体类
        /// 做  者:Blog.Core
        /// </summary>       
        /// <param name="strPath">实体类存放路径</param>
        public void CreateClassFileByDBTalbe(string strPath)
        {
            CreateClassFileByDBTalbe(strPath, "Km.PosZC");
        }
        /// <summary>
        /// 功能描述:根据数据库表生产实体类
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="strPath">实体类存放路径</param>
        /// <param name="strNameSpace">命名空间</param>
        public void CreateClassFileByDBTalbe(string strPath, string strNameSpace)
        {
            CreateClassFileByDBTalbe(strPath, strNameSpace, null);
        }

        /// <summary>
        /// 功能描述:根据数据库表生产实体类
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="strPath">实体类存放路径</param>
        /// <param name="strNameSpace">命名空间</param>
        /// <param name="lstTableNames">生产指定的表</param>
        public void CreateClassFileByDBTalbe(
            string strPath,
            string strNameSpace,
            string[] lstTableNames)
        {
            CreateClassFileByDBTalbe(strPath, strNameSpace, lstTableNames, string.Empty);
        }

        /// <summary>
        /// 功能描述:根据数据库表生产实体类
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="strPath">实体类存放路径</param>
        /// <param name="strNameSpace">命名空间</param>
        /// <param name="lstTableNames">生产指定的表</param>
        /// <param name="strInterface">实现接口</param>
        public void CreateClassFileByDBTalbe(
          string strPath,
          string strNameSpace,
          string[] lstTableNames,
          string strInterface,
          bool blnSerializable = false)
        {
            if (lstTableNames != null && lstTableNames.Length > 0)
            {
                _db.DbFirst.Where(lstTableNames).IsCreateDefaultValue().IsCreateAttribute()
                    .SettingClassTemplate(p => p = @"
{using}

namespace {Namespace}
{
    {ClassDescription}{SugarTable}" + (blnSerializable ? "[Serializable]" : "") + @"
    public partial class {ClassName}" + (string.IsNullOrEmpty(strInterface) ? "" : (" : " + strInterface)) + @"
    {
        public {ClassName}()
        {
{Constructor}
        }
{PropertyName}
    }
}
")
                    .SettingPropertyTemplate(p => p = @"
            {SugarColumn}
            public {PropertyType} {PropertyName}
            {
                get
                {
                    return _{PropertyName};
                }
                set
                {
                    if(_{PropertyName}!=value)
                    {
                        base.SetValueCall(" + "\"{PropertyName}\",_{PropertyName}" + @");
                    }
                    _{PropertyName}=value;
                }
            }")
                    .SettingPropertyDescriptionTemplate(p => p = "          private {PropertyType} _{PropertyName};\r\n" + p)
                    .SettingConstructorTemplate(p => p = "              this._{PropertyName} ={DefaultValue};")
                    .CreateClassFile(strPath, strNameSpace);
            }
            else
            {
                _db.DbFirst.IsCreateAttribute().IsCreateDefaultValue()
                    .SettingClassTemplate(p => p = @"
{using}

namespace {Namespace}
{
    {ClassDescription}{SugarTable}" + (blnSerializable ? "[Serializable]" : "") + @"
    public partial class {ClassName}" + (string.IsNullOrEmpty(strInterface) ? "" : (" : " + strInterface)) + @"
    {
        public {ClassName}()
        {
{Constructor}
        }
{PropertyName}
    }
}
")
                    .SettingPropertyTemplate(p => p = @"
            {SugarColumn}
            public {PropertyType} {PropertyName}
            {
                get
                {
                    return _{PropertyName};
                }
                set
                {
                    if(_{PropertyName}!=value)
                    {
                        base.SetValueCall(" + "\"{PropertyName}\",_{PropertyName}" + @");
                    }
                    _{PropertyName}=value;
                }
            }")
                    .SettingPropertyDescriptionTemplate(p => p = "          private {PropertyType} _{PropertyName};\r\n" + p)
                    .SettingConstructorTemplate(p => p = "              this._{PropertyName} ={DefaultValue};")
                    .CreateClassFile(strPath, strNameSpace);
            }
        }
        #endregion

        #region 根据实体类生成数据库表
        /// <summary>
        /// 功能描述:根据实体类生成数据库表
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="blnBackupTable">是否备份表</param>
        /// <param name="lstEntitys">指定的实体</param>
        public void CreateTableByEntity<T>(bool blnBackupTable, params T[] lstEntitys) where T : class, new()
        {
            Type[] lstTypes = null;
            if (lstEntitys != null)
            {
                lstTypes = new Type[lstEntitys.Length];
                for (int i = 0; i < lstEntitys.Length; i++)
                {
                    T t = lstEntitys[i];
                    lstTypes[i] = typeof(T);
                }
            }
            CreateTableByEntity(blnBackupTable, lstTypes);
        }

        /// <summary>
        /// 功能描述:根据实体类生成数据库表
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="blnBackupTable">是否备份表</param>
        /// <param name="lstEntitys">指定的实体</param>
        public void CreateTableByEntity(bool blnBackupTable, params Type[] lstEntitys)
        {
            if (blnBackupTable)
            {
                _db.CodeFirst.BackupTable().InitTables(lstEntitys); //change entity backupTable            
            }
            else
            {
                _db.CodeFirst.InitTables(lstEntitys);
            }
        }
        #endregion

        #endregion

        #region 静态方法

        /// <summary>
        /// 功能描述:得到一个DbContext
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="blnIsAutoCloseConnection">是否自动关闭链接(若是为false,则使用接受时须要手动关闭Db)</param>
        /// <returns>返回值</returns>
        public static DbContext GetDbContext(bool blnIsAutoCloseConnection = true)
        {
            return new DbContext(blnIsAutoCloseConnection);
        }

        /// <summary>
        /// 功能描述:设置初始化参数
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="strConnectionString">链接字符串</param>
        /// <param name="enmDbType">数据库类型</param>
        public static void Init(string strConnectionString, DbType enmDbType = SqlSugar.DbType.SqlServer)
        {
            _connectionString = strConnectionString;
            _dbType = enmDbType;
        }

        /// <summary>
        /// 功能描述:建立一个连接配置
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="blnIsAutoCloseConnection">是否自动关闭链接</param>
        /// <param name="blnIsShardSameThread">是否夸类事务</param>
        /// <returns>ConnectionConfig</returns>
        public static ConnectionConfig GetConnectionConfig(bool blnIsAutoCloseConnection = true, bool blnIsShardSameThread = false)
        {
            ConnectionConfig config = new ConnectionConfig()
            {
                ConnectionString = _connectionString,
                DbType = _dbType,
                IsAutoCloseConnection = blnIsAutoCloseConnection,
                ConfigureExternalServices = new ConfigureExternalServices()
                {
                    //DataInfoCacheService = new HttpRuntimeCache()
                },
                IsShardSameThread = blnIsShardSameThread
            };
            return config;
        }

        /// <summary>
        /// 功能描述:获取一个自定义的DB
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="config">config</param>
        /// <returns>返回值</returns>
        public static SqlSugarClient GetCustomDB(ConnectionConfig config)
        {
            return new SqlSugarClient(config);
        }
        /// <summary>
        /// 功能描述:获取一个自定义的数据库处理对象
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="sugarClient">sugarClient</param>
        /// <returns>返回值</returns>
        public static SimpleClient<T> GetCustomEntityDB<T>(SqlSugarClient sugarClient) where T : class, new()
        {
            return new SimpleClient<T>(sugarClient);
        }
        /// <summary>
        /// 功能描述:获取一个自定义的数据库处理对象
        /// 做  者:Blog.Core
        /// </summary>
        /// <param name="config">config</param>
        /// <returns>返回值</returns>
        public static SimpleClient<T> GetCustomEntityDB<T>(ConnectionConfig config) where T : class, new()
        {
            SqlSugarClient sugarClient = GetCustomDB(config);
            return GetCustomEntityDB<T>(sugarClient);
        }
        #endregion
    }
}
View Code

 

 

 

二、而后在刚刚咱们实现那四个方法的AdvertisementRepository.cs中,重写构造函数,编辑统一Sqlsugar实例方法,用到了私有属性,为之后的单列模式作准备。

     private DbContext context;
        private SqlSugarClient db;
        private SimpleClient<Advertisement> entityDB;

        internal SqlSugarClient Db
        {
            get { return db; }
            private set { db = value; }
        }
        public DbContext Context
        {
            get { return context; }
            set { context = value; }
        }
        public AdvertisementRepository() {
            DbContext.Init(BaseDBConfig.ConnectionString);
            context = DbContext.GetDbContext();
       db = context.Db; entityDB
= context.GetEntityDB<Advertisement>(db); }

 

三、正式开始写持久化逻辑代码(注意:我在Model层中,添加了全局的数据类型转换方法,UtilConvert,这样就不用每次都Convert,并且也解决了为空转换异常的bug)

    public static class UtilConvert
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <returns></returns>
        public static int ObjToInt(this object thisValue)
        {
            int reval = 0;
            if (thisValue == null) return 0;
            if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return reval;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <param name="errorValue"></param>
        /// <returns></returns>
        public static int ObjToInt(this object thisValue, int errorValue)
        {
            int reval = 0;
            if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return errorValue;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <returns></returns>
        public static double ObjToMoney(this object thisValue)
        {
            double reval = 0;
            if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return 0;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <param name="errorValue"></param>
        /// <returns></returns>
        public static double ObjToMoney(this object thisValue, double errorValue)
        {
            double reval = 0;
            if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return errorValue;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <returns></returns>
        public static string ObjToString(this object thisValue)
        {
            if (thisValue != null) return thisValue.ToString().Trim();
            return "";
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <param name="errorValue"></param>
        /// <returns></returns>
        public static string ObjToString(this object thisValue, string errorValue)
        {
            if (thisValue != null) return thisValue.ToString().Trim();
            return errorValue;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <returns></returns>
        public static Decimal ObjToDecimal(this object thisValue)
        {
            Decimal reval = 0;
            if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return 0;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <param name="errorValue"></param>
        /// <returns></returns>
        public static Decimal ObjToDecimal(this object thisValue, decimal errorValue)
        {
            Decimal reval = 0;
            if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return errorValue;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <returns></returns>
        public static DateTime ObjToDate(this object thisValue)
        {
            DateTime reval = DateTime.MinValue;
            if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
            {
                reval = Convert.ToDateTime(thisValue);
            }
            return reval;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <param name="errorValue"></param>
        /// <returns></returns>
        public static DateTime ObjToDate(this object thisValue, DateTime errorValue)
        {
            DateTime reval = DateTime.MinValue;
            if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return errorValue;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <returns></returns>
        public static bool ObjToBool(this object thisValue)
        {
            bool reval = false;
            if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))
            {
                return reval;
            }
            return reval;
        }
    }
View Code

最终的仓储持久化是:

    public class AdvertisementRepository : IAdvertisementRepository
    {

        private DbContext context;
        private SqlSugarClient db;
        private SimpleClient<Advertisement> entityDB;

        internal SqlSugarClient Db
        {
            get { return db; }
            private set { db = value; }
        }
        public DbContext Context
        {
            get { return context; }
            set { context = value; }
        }
        public AdvertisementRepository() {
            DbContext.Init(BaseDBConfig.ConnectionString);
            context = DbContext.GetDbContext();
       db = context.Db; entityDB
= context.GetEntityDB<Advertisement>(db); } public int Add(Advertisement model) { //返回的i是long类型,这里你能够根据你的业务须要进行处理 var i = db.Insertable(model).ExecuteReturnBigIdentity(); return i.ObjToInt(); } public bool Delete(Advertisement model) { var i = db.Deleteable(model).ExecuteCommand(); return i > 0; } public List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression) { return entityDB.GetList(whereExpression); } public int Sum(int i, int j) { return i + j; } public bool Update(Advertisement model) { //这种方式会以主键为条件 var i = db.Updateable(model).ExecuteCommand(); return i > 0; } }

 

4、在 IServices 层设计服务接口,并 Service 层实现

这里不细说,记得添加引用,最终的代码是:

namespace Blog.Core.IServices
{
    public interface IAdvertisementServices 
    {
        int Sum(int i, int j);
        int Add(Advertisement model);
        bool Delete(Advertisement model);
        bool Update(Advertisement model);
        List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression);
    }
}
namespace Blog.Core.Services
{
    public class AdvertisementServices : IAdvertisementServices
    {
        public IAdvertisementRepository dal = new AdvertisementRepository();
        public int Sum(int i, int j)
        {
            return dal.Sum(i, j);

        }


        public int Add(Advertisement model)
        {
            return dal.Add(model);
        }

        public bool Delete(Advertisement model)
        {
            return dal.Delete(model);
        }

        public List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression)
        {
            return dal.Query(whereExpression);

        }

        public bool Update(Advertisement model)
        {
            return dal.Update(model);
        }

    }
}

都是很简单,若是昨天的Sum方法你会了,这个确定都会。

 

5、Controller测试接口

  实现工做,根据id获取数据

  这里为了调试方便,我把权限验证暂时注释掉

  //[Authorize(Policy ="Admin")]

 

而后修改咱们的其中一个Get方法,根据id获取信息

       // GET: api/Blog/5
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}", Name = "Get")]
        public List<Advertisement> Get(int id)
        {
            IAdvertisementServices advertisementServices = new AdvertisementServices();

            return advertisementServices.Query(d => d.Id == id);
        }
        

接下来运行调试,在咱们接口文档中,直接点击调试

 

 获得的结果是若是,虽然是空的,可是返回结果http代码是200,由于表中没数据嘛

 

6、结语

  好啦,今天的讲解就到这里,你简单的了解了什么是ORM,以及其中的SqlSugar,而后呢,仓储模式的具体使用,最后还有真正的链接数据库,获取到数据,下一节中,咱们继续来解决两大问题,来实现泛型仓储。

 

7、CODE

 https://github.com/anjoy8/Blog.Core.git

https://gitee.com/laozhangIsPhi/Blog.Core