.NET Core實戰項目之CMS 第十二章 開發篇-Dapper封裝CURD及倉儲代碼生成器實現


本篇我將帶着大家一起來對Dapper進行下封裝並實現基本的增刪改查、分頁操作的同步異步方法的實現(已實現MSSQL,MySql,PgSQL)。同時我們再實現一下倉儲層的代碼生成器,這樣的話,我們只需要結合業務來實現具體的業務部分的代碼就可以了,可以大大減少我們重復而又繁瑣的增刪改查操作,多留點時間給生活充充電(不會偷懶的程序員不是一位好爸爸/好老公/好男朋友)。如果您覺得我的實現過程有所不妥的話,您可以在評論區留言,或者加入我們的千人.Net Core實戰項目交流群637326624交流。另外如果您覺得我的文章對您有所幫助的話希望給個推薦以示支持。項目的源代碼我會托管在GayHub上,地址在文章末尾會給出,自認為代碼寫的很工整,注釋也很全,你應該能看懂!

本文已收錄至《.NET Core實戰項目之CMS 第一章 入門篇-開篇及總體規划

作者:依樂祝

原文地址:https://www.cnblogs.com/yilezhu/p/10146311.html

寫在前面

將近一周沒有更新,鬼知道我這么長時間在干什么,你可以認為我在憋大招,在想着怎么給大家分享更多更實用的東西。其實這只是我偷懶的借口罷了!下面我們一起來對Dapper進行下封裝吧,然后結合Dapper.SimpleCRUD 來實現基本的增刪改查、分頁操作。這部分功能實現完成后,往下我們也就是基於這些基本操作來實現我們的CMS的業務了,如:權限部分,菜單部分,文章部分的功能。接下來我會對這部分快速的實現,可能會很少更新了,因為這些都是基本的CMS的業務操作,沒多少要分享的內容,畢竟每個人的系統業務都不一樣,這部分的業務實現也是千差萬別的。我后期會把成品直接分享給大家!敬請關注吧!

Dapper的封裝

IDbConnection工廠類的封裝

這部分我實現了一個IDbConnection的工廠類,以便你可以很方便的根據數據庫的類型來創建不同的IDbConnection對象,目前已實現對SqlServer,MySQL,PostgreSQL的實現,具體代碼如下,根據傳入的參數來進行相關的實現。

	   /// <summary>
    /// yilezhu
    /// 2018.12.13
    /// 數據庫連接工廠類
    /// </summary>
    public class ConnectionFactory
    {
        /// <summary>
        /// 獲取數據庫連接
        /// </summary>
        /// <param name="dbtype">數據庫類型</param>
        /// <param name="conStr">數據庫連接字符串</param>
        /// <returns>數據庫連接</returns>
        public static IDbConnection CreateConnection(string dbtype, string strConn)
        {
            if (dbtype.IsNullOrWhiteSpace())
                throw new ArgumentNullException("獲取數據庫連接居然不傳數據庫類型,你想上天嗎?");
            if (strConn.IsNullOrWhiteSpace())
                throw new ArgumentNullException("獲取數據庫連接居然不傳數據庫類型,你想上天嗎?");
            var dbType = GetDataBaseType(dbtype);
            return CreateConnection(dbType,strConn);
        }

        /// <summary>
        /// 獲取數據庫連接
        /// </summary>
        /// <param name="dbType">數據庫類型</param>
        /// <param name="conStr">數據庫連接字符串</param>
        /// <returns>數據庫連接</returns>
        public static IDbConnection CreateConnection(DatabaseType dbType, string strConn)
        {
            IDbConnection connection = null;           
            if (strConn.IsNullOrWhiteSpace())
                throw new ArgumentNullException("獲取數據庫連接居然不傳數據庫類型,你想上天嗎?");
            
            switch (dbType)
            {
                case DatabaseType.SqlServer:
                    connection = new SqlConnection(strConn);
                    break;
                case DatabaseType.MySQL:
                    connection = new MySqlConnection(strConn);
                    break;
                case DatabaseType.PostgreSQL:
                    connection = new NpgsqlConnection(strConn);
                    break;
                default:
                    throw new ArgumentNullException($"這是我的錯,還不支持的{dbType.ToString()}數據庫類型");

            }
            if (connection.State == ConnectionState.Closed)
            {
                connection.Open();
            }
            return connection;
        }

        /// <summary>
        /// 轉換數據庫類型
        /// </summary>
        /// <param name="dbtype">數據庫類型字符串</param>
        /// <returns>數據庫類型</returns>
        public static DatabaseType GetDataBaseType(string dbtype)
        {
            if (dbtype.IsNullOrWhiteSpace())
                throw new ArgumentNullException("獲取數據庫連接居然不傳數據庫類型,你想上天嗎?");
            DatabaseType returnValue = DatabaseType.SqlServer;
            foreach (DatabaseType dbType in Enum.GetValues(typeof(DatabaseType)))
            {
                if (dbType.ToString().Equals(dbtype, StringComparison.OrdinalIgnoreCase))
                {
                    returnValue = dbType;
                    break;
                }
            }
            return returnValue;
        }

        
    }

那么,我們怎么來使用這個工廠類呢?如下給出調用的實例。

1545221995138

是不是很簡單,感覺瞬間少了很多代碼,這段代碼摘錄自代碼生成器里面。有興趣的自己去查看源碼吧!

CRUD及分頁泛型方法的實現

  1. nuget安裝Dapper.SimpleCRUD ,什么你要問我怎么安裝?乖乖的回去看第二篇文章吧!那里會教你如何安裝Nuget包?如果那篇文章里面沒有,那你就好好想想為啥沒有呢?

    1545222273003

  2. 新建IBaseRepository泛型接口 定義如下的增刪改查方法的同步異步接口,其中還包含分頁的實現,具體的代碼如下:

    /**
    *┌──────────────────────────────────────────────────────────────┐
    *│ 描    述:                                                    
    *│ 作    者:yilezhu                                             
    *│ 版    本:1.0                                                 
    *│ 創建時間:2018/12/16 20:41:22                             
    *└──────────────────────────────────────────────────────────────┘
    *┌──────────────────────────────────────────────────────────────┐
    *│ 命名空間: Czar.Cms.Core.Repository                                   
    *│ 接口名稱: IBaseRepository                                      
    *└──────────────────────────────────────────────────────────────┘
    */
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Czar.Cms.Core.Repository
    {
        public interface IBaseRepository<T,TKey> :  IDisposable where T : class
        {
            #region 同步
            /// <summary>
            /// 通過主鍵獲取實體對象
            /// </summary>
            /// <param name="id">主鍵ID</param>
            /// <returns></returns>
            T Get(TKey id);
            /// <summary>
            /// 獲取所有的數據
            /// </summary>
            /// <returns></returns>
            IEnumerable<T> GetList();
            /// <summary>
            /// 執行具有條件的查詢,並將結果映射到強類型列表
            /// </summary>
            /// <param name="whereConditions">條件</param>
            /// <returns></returns>
            IEnumerable<T> GetList(object whereConditions);
            /// <summary>
            /// 帶參數的查詢滿足條件的數據
            /// </summary>
            /// <param name="conditions">條件</param>
            /// <param name="parameters">參數</param>
            /// <returns></returns>
            IEnumerable<T> GetList(string conditions, object parameters = null);
            /// <summary>
            /// 使用where子句執行查詢,並將結果映射到具有Paging的強類型List
            /// </summary>
            /// <param name="pageNumber">頁碼</param>
            /// <param name="rowsPerPage">每頁顯示數據</param>
            /// <param name="conditions">查詢條件</param>
            /// <param name="orderby">排序</param>
            /// <param name="parameters">參數</param>
            /// <returns></returns>
            IEnumerable<T> GetListPaged(int pageNumber, int rowsPerPage, string conditions, string orderby, object parameters = null);
            /// <summary>
            /// 插入一條記錄並返回主鍵值(自增類型返回主鍵值,否則返回null)
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            int? Insert(T entity);
            /// <summary>
            /// 更新一條數據並返回影響的行數
            /// </summary>
            /// <param name="entity"></param>
            /// <returns>影響的行數</returns>
            int Update(T entity);
            /// <summary>
            /// 根據實體主鍵刪除一條數據
            /// </summary>
            /// <param name="id">主鍵</param>
            /// <returns>影響的行數</returns>
            int Delete(TKey id);
            /// <summary>
            /// 根據實體刪除一條數據
            /// </summary>
            /// <param name="entity">實體</param>
            /// <returns>返回影響的行數</returns>
            int Delete(T entity);
            /// <summary>
            /// 條件刪除多條記錄
            /// </summary>
            /// <param name="whereConditions">條件</param>
            /// <param name="transaction">事務</param>
            /// <param name="commandTimeout">超時時間</param>
            /// <returns>影響的行數</returns>
            int DeleteList(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null);
            /// <summary>
            /// 使用where子句刪除多個記錄
            /// </summary>
            /// <param name="conditions">wher子句</param>
            /// <param name="parameters">參數</param>
            /// <param name="transaction">事務</param>
            /// <param name="commandTimeout">超時時間</param>
            /// <returns>影響的行數</returns>
            int DeleteList(string conditions, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null);
            /// <summary>
            /// 滿足條件的記錄數量
            /// </summary>
            /// <param name="conditions"></param>
            /// <param name="parameters"></param>
            /// <returns></returns>
            int RecordCount(string conditions = "", object parameters = null);
            #endregion
            #region 異步
            /// <summary>
            /// 通過主鍵獲取實體對象
            /// </summary>
            /// <param name="id">主鍵ID</param>
            /// <returns></returns>
            Task<T> GetAsync(TKey id);
            /// <summary>
            /// 獲取所有的數據
            /// </summary>
            /// <returns></returns>
            Task<IEnumerable<T>> GetListAsync();
            /// <summary>
            /// 執行具有條件的查詢,並將結果映射到強類型列表
            /// </summary>
            /// <param name="whereConditions">條件</param>
            /// <returns></returns>
            Task<IEnumerable<T>> GetListAsync(object whereConditions);
            /// <summary>
            /// 帶參數的查詢滿足條件的數據
            /// </summary>
            /// <param name="conditions">條件</param>
            /// <param name="parameters">參數</param>
            /// <returns></returns>
            Task<IEnumerable<T>> GetListAsync(string conditions, object parameters = null);
            /// <summary>
            /// 使用where子句執行查詢,並將結果映射到具有Paging的強類型List
            /// </summary>
            /// <param name="pageNumber">頁碼</param>
            /// <param name="rowsPerPage">每頁顯示數據</param>
            /// <param name="conditions">查詢條件</param>
            /// <param name="orderby">排序</param>
            /// <param name="parameters">參數</param>
            /// <returns></returns>
            Task<IEnumerable<T>> GetListPagedAsync(int pageNumber, int rowsPerPage, string conditions, string orderby, object parameters = null);
            /// <summary>
            /// 插入一條記錄並返回主鍵值
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            Task<int?> InsertAsync(T entity);
            /// <summary>
            /// 更新一條數據並返回影響的行數
            /// </summary>
            /// <param name="entity"></param>
            /// <returns>影響的行數</returns>
            Task<int> UpdateAsync(T entity);
            /// <summary>
            /// 根據實體主鍵刪除一條數據
            /// </summary>
            /// <param name="id">主鍵</param>
            /// <returns>影響的行數</returns>
            Task<int> DeleteAsync(TKey id);
            /// <summary>
            /// 根據實體刪除一條數據
            /// </summary>
            /// <param name="entity">實體</param>
            /// <returns>返回影響的行數</returns>
            Task<int> DeleteAsync(T entity);
            /// <summary>
            /// 條件刪除多條記錄
            /// </summary>
            /// <param name="whereConditions">條件</param>
            /// <param name="transaction">事務</param>
            /// <param name="commandTimeout">超時時間</param>
            /// <returns>影響的行數</returns>
            Task<int> DeleteListAsync(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null);
            /// <summary>
            /// 使用where子句刪除多個記錄
            /// </summary>
            /// <param name="conditions">wher子句</param>
            /// <param name="parameters">參數</param>
            /// <param name="transaction">事務</param>
            /// <param name="commandTimeout">超時時間</param>
            /// <returns>影響的行數</returns>
            Task<int> DeleteListAsync(string conditions, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null);
            /// <summary>
            /// 滿足條件的記錄數量
            /// </summary>
            /// <param name="conditions"></param>
            /// <param name="parameters"></param>
            /// <returns></returns>
            Task<int> RecordCountAsync(string conditions = "", object parameters = null);
            #endregion
        }
    }
    
    
  3. 然后創建一個BaseRepository泛型類來實現上面的接口,其中多了兩個成員,DbOpion以及IDbConnection,猜猜看這兩個東西有什么用?后面給出答案

    /**
    *┌──────────────────────────────────────────────────────────────┐
    *│ 描    述:倉儲類的基類                                                    
    *│ 作    者:yilezhu                                             
    *│ 版    本:1.0                                                 
    *│ 創建時間:2018/12/16 12:03:02                             
    *└──────────────────────────────────────────────────────────────┘
    *┌──────────────────────────────────────────────────────────────┐
    *│ 命名空間: Czar.Cms.Core.Repository                                   
    *│ 類    名: BaseRepository                                      
    *└──────────────────────────────────────────────────────────────┘
    */
    using Czar.Cms.Core.DbHelper;
    using Czar.Cms.Core.Options;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Text;
    using System.Threading.Tasks;
    using Dapper;
    
    namespace Czar.Cms.Core.Repository
    {
        public class BaseRepository<T, TKey> : IBaseRepository<T, TKey> where T : class
        {
            protected DbOpion _dbOpion;
            protected IDbConnection _dbConnection;
    
            //public BaseRepository(DbOpion dbOpion)
            //{
            //    _dbOpion = dbOpion ?? throw new ArgumentNullException(nameof(DbOpion));
            //    _dbConnection = ConnectionFactory.CreateConnection(_dbOpion.DbType, _dbOpion.ConnectionString);
            //}
    
            #region 同步
    
            public T Get(TKey id) => _dbConnection.Get<T>(id);
            public IEnumerable<T> GetList() => _dbConnection.GetList<T>();
    
            public IEnumerable<T> GetList(object whereConditions) => _dbConnection.GetList<T>(whereConditions);
    
            public IEnumerable<T> GetList(string conditions, object parameters = null) => _dbConnection.GetList<T>(conditions, parameters);
    
            public IEnumerable<T> GetListPaged(int pageNumber, int rowsPerPage, string conditions, string orderby, object parameters = null)
            {
                return _dbConnection.GetListPaged<T>(pageNumber, rowsPerPage, conditions, orderby, parameters);
            }
            public int? Insert(T entity) => _dbConnection.Insert(entity);
            public int Update(T entity) => _dbConnection.Update(entity);
    
            public int Delete(TKey id) => _dbConnection.Delete<T>(id);
    
            public int Delete(T entity) => _dbConnection.Delete(entity);
            public int DeleteList(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null)
            {
                return _dbConnection.DeleteList<T>(whereConditions, transaction, commandTimeout);
            }
    
            public int DeleteList(string conditions, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null)
            {
                return _dbConnection.DeleteList<T>(conditions, parameters, transaction, commandTimeout);
            }
            public int RecordCount(string conditions = "", object parameters = null)
            {
                return _dbConnection.RecordCount<T>(conditions, parameters);
            }
            #endregion
    
            #region 異步
            public async Task<T> GetAsync(TKey id)
            {
                return await _dbConnection.GetAsync<T>(id);
            }
    
            public async Task<IEnumerable<T>> GetListAsync()
            {
                return await _dbConnection.GetListAsync<T>();
            }
    
            public async Task<IEnumerable<T>> GetListAsync(object whereConditions)
            {
                return await _dbConnection.GetListAsync<T>(whereConditions);
            }
    
            public async Task<IEnumerable<T>> GetListAsync(string conditions, object parameters = null)
            {
                return await _dbConnection.GetListAsync<T>(conditions, parameters);
            }
            public async Task<IEnumerable<T>> GetListPagedAsync(int pageNumber, int rowsPerPage, string conditions, string orderby, object parameters = null)
            {
                return await _dbConnection.GetListPagedAsync<T>(pageNumber, rowsPerPage, conditions, orderby, parameters);
            }
            public async Task<int?> InsertAsync(T entity)
            {
                return await _dbConnection.InsertAsync(entity);
            }
            public async Task<int> UpdateAsync(T entity)
            {
                return await _dbConnection.UpdateAsync(entity);
            }
            public async Task<int> DeleteAsync(TKey id)
            {
                return await _dbConnection.DeleteAsync(id);
            }
    
            public async Task<int> DeleteAsync(T entity)
            {
                return await _dbConnection.DeleteAsync(entity);
            }
    
    
            public async Task<int> DeleteListAsync(object whereConditions, IDbTransaction transaction = null, int? commandTimeout = null)
            {
                return await _dbConnection.DeleteListAsync<T>(whereConditions, transaction, commandTimeout);
            }
    
            public async Task<int> DeleteListAsync(string conditions, object parameters = null, IDbTransaction transaction = null, int? commandTimeout = null)
            {
                return await DeleteListAsync(conditions, parameters, transaction, commandTimeout);
            }
            public async Task<int> RecordCountAsync(string conditions = "", object parameters = null)
            {
                return await _dbConnection.RecordCountAsync<T>(conditions, parameters);
            }
            #endregion
    
            #region IDisposable Support
            private bool disposedValue = false; // 要檢測冗余調用
    
            protected virtual void Dispose(bool disposing)
            {
                if (!disposedValue)
                {
                    if (disposing)
                    {
                        // TODO: 釋放托管狀態(托管對象)。
                    }
    
                    // TODO: 釋放未托管的資源(未托管的對象)並在以下內容中替代終結器。
                    // TODO: 將大型字段設置為 null。
    
                    disposedValue = true;
                }
            }
    
            // TODO: 僅當以上 Dispose(bool disposing) 擁有用於釋放未托管資源的代碼時才替代終結器。
            // ~BaseRepository() {
            //   // 請勿更改此代碼。將清理代碼放入以上 Dispose(bool disposing) 中。
            //   Dispose(false);
            // }
    
            // 添加此代碼以正確實現可處置模式。
            public void Dispose()
            {
                // 請勿更改此代碼。將清理代碼放入以上 Dispose(bool disposing) 中。
                Dispose(true);
                // TODO: 如果在以上內容中替代了終結器,則取消注釋以下行。
                // GC.SuppressFinalize(this);
            }
            #endregion
        }
    }
    
    

    你沒看錯?我在16號就已經寫好了,為什么這么晚才寫博客分享出來呢?因為我懶~~~~~~~

  4. 這里需要注意,需要安裝SimpleCRUD的Nuget包。另外其他的倉儲方法只需要繼承這個接口以及實現就能夠實現基本的增刪改查操作了。這里你應該會想,既然繼承就能實現,那何不寫一個倉儲的代碼生成器來進行生成呢?說干就干,下面我們就來實現倉儲的代碼生成器

倉儲層代碼生成器

上篇生成數據庫實體的代碼生成器不知道大家看了沒有,這里我們只需要在根據每個數據庫表生成數據庫實體的實體順帶着生成下倉儲接口以及倉儲代碼就可以了。有了思路,我們就擼起袖子加油干吧

  1. 先寫一下倉儲接口代碼生成器的模板,如下所示:

    1545225197161

  2. 再寫一下倉儲層的代碼實現,這里需要注意一下,需要根據注入的IOptionsSnapshot 來生成_dbOpion以及_dbConnection,上面留給大家的思考題答案就在這里,如下所示:

    /**
    *┌──────────────────────────────────────────────────────────────┐
    *│ 描    述:{Comment}接口實現                                                    
    *│ 作    者:{Author}                                            
    *│ 版    本:1.0    模板代碼自動生成                                                
    *│ 創建時間:{GeneratorTime}                             
    *└──────────────────────────────────────────────────────────────┘
    *┌──────────────────────────────────────────────────────────────┐
    *│ 命名空間: {RepositoryNamespace}                                  
    *│ 類    名: {ModelName}Repository                                      
    *└──────────────────────────────────────────────────────────────┘
    */
    using Czar.Cms.Core.DbHelper;
    using Czar.Cms.Core.Options;
    using Czar.Cms.Core.Repository;
    using Czar.Cms.IRepository;
    using Czar.Cms.Models;
    using Microsoft.Extensions.Options;
    using System;
    
    namespace {RepositoryNamespace}
    {
        public class {ModelName}Repository:BaseRepository<{ModelName},{KeyTypeName}>, I{ModelName}Repository
        {
            public {ModelName}Repository(IOptionsSnapshot<DbOpion> options)
            {
                _dbOpion =options.Get("CzarCms");
                if (_dbOpion == null)
                {
                    throw new ArgumentNullException(nameof(DbOpion));
                }
                _dbConnection = ConnectionFactory.CreateConnection(_dbOpion.DbType, _dbOpion.ConnectionString);
            }
    
        }
    }
    
  3. 接着就是代碼生成器生成IRepository以及生成Repository的代碼了!這部分代碼如下圖所示:

    1545225567381

    1545225578141

測試代碼

  1. 重新執行下代碼生成器的代碼,測試的具體代碼我已經放在GitHub上了,這里就不貼出來了,直接上生成結果如下圖所示:

    1545225741822

  2. 如上圖所示:一次性生成了Models以及Repository,IRepository的代碼,然后到每個文件夾里面把對應的代碼拷貝到對應的項目里面吧。然后我們隨便打開一下倉儲以及倉儲接口看下生成后的代碼如下所示:

    /**
    *┌──────────────────────────────────────────────────────────────┐
    *│ 描    述:文章分類                                                    
    *│ 作    者:yilezhu                                              
    *│ 版    本:1.0   模板代碼自動生成                                              
    *│ 創建時間:2018-12-18 13:28:43                           
    *└──────────────────────────────────────────────────────────────┘
    *┌──────────────────────────────────────────────────────────────┐
    *│ 命名空間: Czar.Cms.IRepository                                   
    *│ 接口名稱: IArticleCategoryRepository                                      
    *└──────────────────────────────────────────────────────────────┘
    */
    using Czar.Cms.Core.Repository;
    using Czar.Cms.Models;
    using System;
    
    namespace Czar.Cms.IRepository
    {
        public interface IArticleCategoryRepository : IBaseRepository<ArticleCategory, Int32>
        {
        }
    }
    
    /**
    *┌──────────────────────────────────────────────────────────────┐
    *│ 描    述:文章分類接口實現                                                    
    *│ 作    者:yilezhu                                            
    *│ 版    本:1.0    模板代碼自動生成                                                
    *│ 創建時間:2018-12-18 13:28:43                             
    *└──────────────────────────────────────────────────────────────┘
    *┌──────────────────────────────────────────────────────────────┐
    *│ 命名空間: Czar.Cms.Repository.SqlServer                                  
    *│ 類    名: ArticleCategoryRepository                                      
    *└──────────────────────────────────────────────────────────────┘
    */
    using Czar.Cms.Core.DbHelper;
    using Czar.Cms.Core.Options;
    using Czar.Cms.Core.Repository;
    using Czar.Cms.IRepository;
    using Czar.Cms.Models;
    using Microsoft.Extensions.Options;
    using System;
    
    namespace Czar.Cms.Repository.SqlServer
    {
        public class ArticleCategoryRepository:BaseRepository<ArticleCategory,Int32>, IArticleCategoryRepository
        {
            public ArticleCategoryRepository(IOptionsSnapshot<DbOpion> options)
            {
                _dbOpion =options.Get("CzarCms");
                if (_dbOpion == null)
                {
                    throw new ArgumentNullException(nameof(DbOpion));
                }
                _dbConnection = ConnectionFactory.CreateConnection(_dbOpion.DbType, _dbOpion.ConnectionString);
            }
    
        }
    }
    
  3. 在倉儲層以及倉儲接口層添加對Czar.Cms.Core的引用,當然你也可以通過Nuget包來進行安裝

    Install-Package Czar.Cms.Core -Version 0.1.3
    
  4. 最后在測試代碼中進行測試,這里以ArticleCategoryRepository為例進行測試:

    [Fact]
            public void TestBaseFactory()
            {
                IServiceProvider serviceProvider = BuildServiceForSqlServer();
                IArticleCategoryRepository categoryRepository = serviceProvider.GetService<IArticleCategoryRepository>();
                var category = new ArticleCategory
                {
                    Title = "隨筆",
                    ParentId = 0,
                    ClassList = "",
                    ClassLayer = 0,
                    Sort = 0,
                    ImageUrl = "",
                    SeoTitle = "隨筆的SEOTitle",
                    SeoKeywords = "隨筆的SeoKeywords",
                    SeoDescription = "隨筆的SeoDescription",
                    IsDeleted = false,
                };
                var categoryId = categoryRepository.Insert(category);
                var list = categoryRepository.GetList();
                Assert.True(1 == list.Count());
                Assert.Equal("隨筆", list.FirstOrDefault().Title);
                Assert.Equal("SQLServer", DatabaseType.SqlServer.ToString(), ignoreCase: true);
                categoryRepository.Delete(categoryId.Value);
                var count = categoryRepository.RecordCount();
                Assert.True(0 == count);
    
  5. 測試結果如下所示,都已經測試成功了:

    1545226136210

開原地址

這個系列教程的源碼我會開放在GitHub以及碼雲上,有興趣的朋友可以下載查看!覺得不錯的歡迎Star

GitHub:https://github.com/yilezhu/Czar.Cms

碼雲:https://gitee.com/yilezhu/Czar.Cms

如果你覺得這個系列對您有所幫助的話,歡迎以各種方式進行贊助,當然給個Star支持下也是可以滴!另外一種最簡單粗暴的方式就是下面這種直接關注我們的公眾號了: img

第一時間收到更新推送。

總結

一路走來,已經更新到第十二篇了,到這里大伙已經可以基於這個Dapper的封裝進行自己的業務系統的開發了!當然接下來我會繼續完成我們既定的CMS系統的業務功能開發,接下來可以用來分享的東西就很少了,所以我更多的是開發然后把代碼更新到GitHub以及碼雲上,想看最新的代碼就獲取dev分支的代碼,有問題的可以提issue或者群里討論!敬請期待吧!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM