從壹開始先後端分離【 .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

相關文章
相關標籤/搜索