之前介绍了基于Dapper二次封装了一个易用的ORM工具类:SqlDapperUtil,这个在.NET FX下还是比较好用的,现在都流行.NET CORE,故我这边再次进行精简修改,以便适应.NET CORE并支持依赖注入。
-
提取定义了一个通用访问数据的接口:
public interface IDbAccesser { void Commit(); bool ExecuteCommand(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null); T GetDynamicModel
(Func , T> buildModelFunc, string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null); Dictionary GetFirstValues(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null); T GetModel (string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null) where T : class; List GetModelList (string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) where T : class; List GetMultModelList (string sql, Type[] types, Func -
精简版的Dapper封装操作类:SqlDapperEasyUtil:
///
/// 基于Dapper的数据操作类封装的工具类(简易版) /// Author:左文俊 /// Date:2019/6/28 /// 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(Func 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; } } /// /// 获取一个事务对象(如果需要确保多条执行语句的一致性,必需使用事务) /// /// ///private IDbTransaction GetDbTransaction(IsolationLevel il = IsolationLevel.Unspecified) { return GetDbConnection().BeginTransaction(il); } #endregion public SqlDapperEasyUtil(string connStr) { dbConnectionString = connStr; } /// /// 使用事务 /// public void UseDbTransaction() { useDbTransaction = true; } ////// 获取一个值,param可以是SQL参数也可以是匿名对象 /// ////// /// /// /// /// /// public T GetValue (string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null) { return UseDbConnection((dbConn) => { return dbConn.ExecuteScalar (sql, param, dbTransaction, commandTimeout, commandType); }); } /// /// 获取第一行的所有值,param可以是SQL参数也可以是匿名对象 /// /// /// /// /// /// ///public Dictionary GetFirstValues(string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null) { return UseDbConnection((dbConn) => { Dictionary firstValues = new Dictionary (); List indexColNameMappings = new List (); 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; }); } /// /// 获取一个数据模型实体类,param可以是SQL参数也可以是匿名对象 /// ////// /// /// /// /// /// public T GetModel (string sql, object param = null, int? commandTimeout = null, CommandType? commandType = null) where T : class { return UseDbConnection((dbConn) => { return dbConn.QueryFirstOrDefault (sql, param, dbTransaction, commandTimeout, commandType); }); } /// /// 获取符合条件的所有数据模型实体类列表,param可以是SQL参数也可以是匿名对象 /// ////// /// /// /// /// /// /// public List GetModelList (string sql, object param = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) where T : class { return UseDbConnection((dbConn) => { return dbConn.Query (sql, param, dbTransaction, buffered, commandTimeout, commandType).ToList(); }); } /// /// 获取符合条件的所有数据并根据动态构建Model类委托来创建合适的返回结果(适用于临时性结果且无对应的模型实体类的情况) /// ////// /// /// /// /// /// /// public T GetDynamicModel (Func , 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); } /// /// 获取符合条件的所有指定返回结果对象的列表(复合对象【如:1对多,1对1】),param可以是SQL参数也可以是匿名对象 /// ////// /// /// /// /// /// /// /// /// /// public List GetMultModelList (string sql, Type[] types, Func -
在ASP.NET CORE中应用:
//1.在Startup.ConfigureServices方法注入依赖 //如果在多个并发场景中使用,建议使用:AddTransient services.AddScoped
(provider => { string connStr = provider.GetService ().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 logger; private IDbAccesser dbAccesser; public RealNameCheckService(ILogger logger, IDbAccesser dbAccesser) { this.logger = logger; this.dbAccesser = dbAccesser; } //其它方法代码(如:PushRealNameCheck方法),在此省略... //若需操作DB,则可使用dbAccesser变即可。 } 如有疑问或好的建议,欢迎评论交流。