SqlDapperEasyUtil:.NET CORE下的Dapper封装操作类
之前介绍了基于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<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();
}
精简版的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
{ }
} }
在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变即可。
}
如有疑问或好的建议,欢迎评论交流。
SqlDapperEasyUtil:.NET CORE下的Dapper封装操作类的更多相关文章
- 在 .NET Core 下使用 SixLabors.ImageSharp 操作图片文件(放大、缩小、裁剪、加水印等等)的几个小示例
1. 基础 1.1 将图片的宽度和高度缩小一半 直接贴代码了: <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup ...
- 一个比较常用的关于php下的mysql数据操作类
<?php /************************************************************* MySql类封装: 首先连接数据库,需要有参数 参数如何 ...
- .Net Framework下对Dapper二次封装迁移到.Net Core2.0遇到的问题以及对Dapper的封装介绍
今天成功把.Net Framework下使用Dapper进行封装的ORM成功迁移到.Net Core 2.0上,在迁移的过程中也遇到一些很有意思的问题,值得和大家分享一下.下面我会还原迁移的每一个过程 ...
- Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类
本文目录 1. 前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...
- 七、.net core下配置、数据库访问等操作实现
配置读取 .net core下读取配置还是有点麻烦的,本身没有System.Configuration.dll,所以在进行配置前需要自行引用Microsoft.Extensions.Configura ...
- .NET Core中使用Dapper操作Oracle存储过程最佳实践
为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为OracleDbType.RefCursor,输出为:ParameterDir ...
- NET Core中使用Dapper操作Oracle存储过程
.NET Core中使用Dapper操作Oracle存储过程最佳实践 为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为Or ...
- # .NET Core下操作Git,自动提交代码到
.NET Core下操作Git,自动提交代码到 转自博客园(阿星Plus) .NET Core 3.0 预览版发布已经好些时日了,博客园也已将其用于生产环境中,可见 .NET Core 日趋成熟 回归 ...
- .net core下对于Excel的一些操作及使用
原文:.net core下对于Excel的一些操作及使用 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.cs ...
- net core体系-web应用程序-4asp.net core2.0 项目实战(1)-5项目数据库操作封装操作-EF框架
EF框架有三种基本的方式:DB First(数据库优先),Model First(模型优先),Code First(代码优先). Entity Framework4.1之前EF支持“Database ...
随机推荐
- 深入学习和理解 Redux
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/jhgQXKp4srsl9_VYMTZXjQ作者:曾超 Redux官网上是这样描述Redux, ...
- 强烈建议收藏,python库大全
Python常用库大全及简要说明 本文为大家罗列了Python开发的常用库和各个库的简要说明以及Python开发工具,包管理,环境管理等其它常用资源和Python学习资料.本文只罗列了一部分,完整内容 ...
- vue中form组件中上传el-upload(单、多附件上传,以及上传回显以及编辑不出现等问题)
https://blog.csdn.net/weixin_46565787/article/details/121934075?spm=1001.2101.3001.6650.2&utm_me ...
- 元素可视区client系列
client翻译过来就是客户端,我们使用client系列的相关属性来获取元素可视区的相关信息. 通过client系列的相关属性可以动态的得到该元素的边框大小.元素大小等. client系列属性 作用 ...
- .NET CORE实战项目之CMS 开发篇 思维导图
导图地址下载: 链接:https://pan.baidu.com/s/1sGiNZI-pc_yueqQiddvImQ 提取码:ql4v -------------------------------- ...
- 基于java+springboot的旅游信息网站、旅游景区门票管理系统
该系统是基于java+springboot开发的旅游景区门票管理系统.是给师弟开发的大四实习作品.学习过程中,遇到问题可以咨询github作者. 演示地址 前台地址: http://travel.gi ...
- 你老了,别搞IT了……
你老了,别搞IT了-- [来源]
- 【scikit-learn基础】--『回归模型评估』之偏差分析
模型评估在统计学和机器学习中具有至关重要,它帮助我们主要目标是量化模型预测新数据的能力. 本篇主要介绍模型评估时,如何利用scikit-learn帮助我们快速进行各种偏差的分析. 1. **R² ** ...
- [转帖]ORA-01450 maximum key length (3215) exceeded
一. 问题背景 给一个业务表online建索引时遇到了ORA-01450 maximum key length (3215) exceeded报错,看字面意思是字段太长了,检查表字段类型发现基本都是n ...
- [转帖]History of Unicode Release and Publication Dates
www.unicode.org For ease of reference, this page collects together information about the dates for v ...