SqlDapperEasyUtil:.NET CORE下的Dapper封裝操作類


之前介紹了基於Dapper二次封裝了一個易用的ORM工具類:SqlDapperUtil,這個在.NET FX下還是比較好用的,現在都流行.NET CORE,故我這邊再次進行精簡修改,以便適應.NET CORE並支持依賴注入。

  1. 提取定義了一個通用訪問數據的接口:

    public interface IDbAccesser
        {
            void Commit();
            bool ExecuteCommand(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null);
            T GetDynamicModel<T>(Func<IEnumerable<dynamic>, T> buildModelFunc, string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null);
            Dictionary<string, dynamic> GetFirstValues(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null);
            T GetModel<T>(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null) where T : class;
            List<T> GetModelList<T>(string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) where T : class;
            List<T> GetMultModelList<T>(string sql, Type[] types, Func<object[], T> map, object param = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null);
            T GetValue<T>(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null);
            void Rollback();
            void UseDbTransaction();
        }
    
  2. 精簡版的Dapper封裝操作類:SqlDapperEasyUtil:

        /// <summary>
        /// 基於Dapper的數據操作類封裝的工具類(簡易版)
        /// Author:左文俊
        /// Date:2019/6/28
        /// </summary>
        public class SqlDapperEasyUtil : IDbAccesser
        {
            private readonly string dbConnectionString = null;
            private const string dbProviderName = "System.Data.SqlClient";
            private IDbConnection dbConnection = null;
            private bool useDbTransaction = false;
            private IDbTransaction dbTransaction = null;
    
            static SqlDapperEasyUtil()
            {
                DbProviderFactories.RegisterFactory(dbProviderName, SqlClientFactory.Instance);//.NET CORE需先提前注冊
            }
    
            #region 私有方法
    
            private IDbConnection GetDbConnection()
            {
                bool needCreateNew = false;
                if (dbConnection == null || string.IsNullOrWhiteSpace(dbConnection.ConnectionString))
                {
                    needCreateNew = true;
                }
    
                if (needCreateNew)
                {
                    var dbProviderFactory = DbProviderFactories.GetFactory(dbProviderName);
                    dbConnection = dbProviderFactory.CreateConnection();
                    dbConnection.ConnectionString = dbConnectionString;
                }
    
                if (dbConnection.State == ConnectionState.Closed)
                {
                    dbConnection.Open();
                }
    
                return dbConnection;
            }
    
    
    
            private T UseDbConnection<T>(Func<IDbConnection, T> queryOrExecSqlFunc)
            {
                IDbConnection dbConn = null;
    
                try
                {
                    dbConn = GetDbConnection();
                    if (useDbTransaction && dbTransaction == null)
                    {
                        dbTransaction = GetDbTransaction();
                    }
    
                    return queryOrExecSqlFunc(dbConn);
                }
                catch
                {
                    throw;
                }
                finally
                {
                    if (dbTransaction == null && dbConn != null)
                    {
                        CloseDbConnection(dbConn);
                    }
                }
            }
    
            private void CloseDbConnection(IDbConnection dbConn, bool disposed = false)
            {
                if (dbConn != null)
                {
                    if (disposed && dbTransaction != null)
                    {
                        dbTransaction.Rollback();
                        dbTransaction.Dispose();
                        dbTransaction = null;
                    }
    
                    if (dbConn.State != ConnectionState.Closed)
                    {
                        dbConn.Close();
                    }
                    dbConn.Dispose();
                    dbConn = null;
                }
            }
    
            /// <summary>
            /// 獲取一個事務對象(如果需要確保多條執行語句的一致性,必需使用事務)
            /// </summary>
            /// <param name="il"></param>
            /// <returns></returns>
            private IDbTransaction GetDbTransaction(IsolationLevel il = IsolationLevel.Unspecified)
            {
                return GetDbConnection().BeginTransaction(il);
            }
    
    
            #endregion
    
            public SqlDapperEasyUtil(string connStr)
            {
                dbConnectionString = connStr;
            }
    
    
            /// <summary>
            /// 使用事務
            /// </summary>
            public void UseDbTransaction()
            {
                useDbTransaction = true;
            }
    
    
            /// <summary>
            /// 獲取一個值,param可以是SQL參數也可以是匿名對象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <param name="transaction"></param>
            /// <param name="commandTimeout"></param>
            /// <param name="commandType"></param>
            /// <returns></returns>
            public T GetValue<T>(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null)
            {
                return UseDbConnection((dbConn) =>
                 {
                     return dbConn.ExecuteScalar<T>(sql, param, dbTransaction, commandTimeout, commandType);
                 });
            }
    
            /// <summary>
            /// 獲取第一行的所有值,param可以是SQL參數也可以是匿名對象
            /// </summary>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <param name="transaction"></param>
            /// <param name="commandTimeout"></param>
            /// <param name="commandType"></param>
            /// <returns></returns>
            public Dictionary<string, dynamic> GetFirstValues(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null)
            {
                return UseDbConnection((dbConn) =>
                {
                    Dictionary<string, dynamic> firstValues = new Dictionary<string, dynamic>();
                    List<string> indexColNameMappings = new List<string>();
                    int rowIndex = 0;
                    using (var reader = dbConn.ExecuteReader(sql, param, dbTransaction, commandTimeout, commandType))
                    {
                        while (reader.Read())
                        {
                            if ((++rowIndex) > 1) break;
                            if (indexColNameMappings.Count == 0)
                            {
                                for (int i = 0; i < reader.FieldCount; i++)
                                {
                                    indexColNameMappings.Add(reader.GetName(i));
                                }
                            }
    
                            for (int i = 0; i < reader.FieldCount; i++)
                            {
                                firstValues[indexColNameMappings[i]] = reader.GetValue(i);
                            }
                        }
                        reader.Close();
                    }
    
                    return firstValues;
    
                });
            }
    
            /// <summary>
            /// 獲取一個數據模型實體類,param可以是SQL參數也可以是匿名對象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <param name="transaction"></param>
            /// <param name="commandTimeout"></param>
            /// <param name="commandType"></param>
            /// <returns></returns>
            public T GetModel<T>(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null) where T : class
            {
                return UseDbConnection((dbConn) =>
                {
                    return dbConn.QueryFirstOrDefault<T>(sql, param, dbTransaction, commandTimeout, commandType);
                });
            }
    
            /// <summary>
            /// 獲取符合條件的所有數據模型實體類列表,param可以是SQL參數也可以是匿名對象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <param name="transaction"></param>
            /// <param name="buffered"></param>
            /// <param name="commandTimeout"></param>
            /// <param name="commandType"></param>
            /// <returns></returns>
            public List<T> GetModelList<T>(string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) where T : class
            {
                return UseDbConnection((dbConn) =>
                {
                    return dbConn.Query<T>(sql, param, dbTransaction, buffered, commandTimeout, commandType).ToList();
                });
            }
    
            /// <summary>
            /// 獲取符合條件的所有數據並根據動態構建Model類委托來創建合適的返回結果(適用於臨時性結果且無對應的模型實體類的情況)
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="buildModelFunc"></param>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <param name="buffered"></param>
            /// <param name="commandTimeout"></param>
            /// <param name="commandType"></param>
            /// <returns></returns>
            public T GetDynamicModel<T>(Func<IEnumerable<dynamic>, T> buildModelFunc, string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
            {
                var dynamicResult = UseDbConnection((dbConn) =>
               {
                   return dbConn.Query(sql, param, dbTransaction, buffered, commandTimeout, commandType);
               });
    
                return buildModelFunc(dynamicResult);
            }
    
            /// <summary>
            /// 獲取符合條件的所有指定返回結果對象的列表(復合對象【如:1對多,1對1】),param可以是SQL參數也可以是匿名對象
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sql"></param>
            /// <param name="types"></param>
            /// <param name="map"></param>
            /// <param name="param"></param>
            /// <param name="transaction"></param>
            /// <param name="buffered"></param>
            /// <param name="splitOn"></param>
            /// <param name="commandTimeout"></param>
            /// <param name="commandType"></param>
            /// <returns></returns>
    
            public List<T> GetMultModelList<T>(string sql, Type[] types, Func<object[], T> map, object param = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null)
            {
                return UseDbConnection((dbConn) =>
                {
                    return dbConn.Query<T>(sql, types, map, param, dbTransaction, buffered, splitOn, commandTimeout, commandType).ToList();
                });
            }
    
    
    
    
            /// <summary>
            /// 執行SQL命令(CRUD),param可以是SQL參數也可以是要添加的實體類
            /// </summary>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <param name="transaction"></param>
            /// <param name="commandTimeout"></param>
            /// <param name="commandType"></param>
            /// <returns></returns>
            public bool ExecuteCommand(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null)
            {
                return UseDbConnection((dbConn) =>
                {
                    int result = dbConn.Execute(sql, param, dbTransaction, commandTimeout, commandType);
                    return (result > 0);
                });
            }
    
    
    
            /// <summary>
            /// 當使用了事務,則最后需要調用該方法以提交所有操作
            /// </summary>
            /// <param name="dbTransaction"></param>
            public void Commit()
            {
                try
                {
                    if (dbTransaction.Connection != null && dbTransaction.Connection.State != ConnectionState.Closed)
                    {
                        dbTransaction.Commit();
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    if (dbTransaction.Connection != null)
                    {
                        CloseDbConnection(dbTransaction.Connection);
                    }
                    dbTransaction.Dispose();
                    dbTransaction = null;
                    useDbTransaction = false;
    
                    if (dbConnection != null)
                    {
                        CloseDbConnection(dbConnection);
                    }
                }
            }
    
            /// <summary>
            /// 當使用了事務,如果報錯或需要中斷執行,則需要調用該方法執行回滾操作
            /// </summary>
            /// <param name="dbTransaction"></param>
            public void Rollback()
            {
                try
                {
                    if (dbTransaction.Connection != null && dbTransaction.Connection.State != ConnectionState.Closed)
                    {
                        dbTransaction.Rollback();
                    }
                }
                catch
                {
                    throw;
                }
                finally
                {
                    if (dbTransaction.Connection != null)
                    {
                        CloseDbConnection(dbTransaction.Connection);
                    }
    
                    dbTransaction.Dispose();
                    dbTransaction = null;
                    useDbTransaction = false;
                }
            }
    
            ~SqlDapperEasyUtil()
            {
                try
                {
                    CloseDbConnection(dbConnection, true);
                }
                catch
                { }
            }
    
        }
    
  3. 在ASP.NET CORE中應用:

    //1.在Startup.ConfigureServices方法注入依賴
    //如果在多個並發場景中使用,建議使用:AddTransient
     services.AddScoped<IDbAccesser>(provider =>
                {
                    string connStr = provider.GetService<IConfiguration>().GetConnectionString("配置連接的name");
                    return new SqlDapperEasyUtil(connStr);
                });
    
    //2.在具體的controller、service中通過構造函數注入或其它方式注入獲取實例,如:
            [Route("PushRealNameCheck")]
            [HttpPost]
            public ApiResult PushRealNameCheck([FromServices] RealNameCheckService realNameCheckService, [FromBody]RealNameCheckReqeust realNameCheckReqeust)
            {
                return realNameCheckService.PushRealNameCheck(realNameCheckReqeust);
            }
    
    
    
        public class RealNameCheckService
        {
            private ILogger<RealNameCheckService> logger;
            private IDbAccesser dbAccesser;
            public RealNameCheckService(ILogger<RealNameCheckService> logger, IDbAccesser dbAccesser)
            {
                this.logger = logger;
                this.dbAccesser = dbAccesser;
            }
            
            //其它方法代碼(如:PushRealNameCheck方法),在此省略...
            //若需操作DB,則可使用dbAccesser變即可。
        }
    

    如有疑問或好的建議,歡迎評論交流。


免責聲明!

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



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