之前介绍了基于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变即可。
    }

    如有疑问或好的建议,欢迎评论交流。

SqlDapperEasyUtil:.NET CORE下的Dapper封装操作类的更多相关文章

  1. 在 .NET Core 下使用 SixLabors.ImageSharp 操作图片文件(放大、缩小、裁剪、加水印等等)的几个小示例

    1. 基础 1.1  将图片的宽度和高度缩小一半 直接贴代码了: <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup ...

  2. 一个比较常用的关于php下的mysql数据操作类

    <?php /************************************************************* MySql类封装: 首先连接数据库,需要有参数 参数如何 ...

  3. .Net Framework下对Dapper二次封装迁移到.Net Core2.0遇到的问题以及对Dapper的封装介绍

    今天成功把.Net Framework下使用Dapper进行封装的ORM成功迁移到.Net Core 2.0上,在迁移的过程中也遇到一些很有意思的问题,值得和大家分享一下.下面我会还原迁移的每一个过程 ...

  4. Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类

    本文目录 1.  前沿 2.CacheHelper基于Microsoft.Extensions.Caching.Memory封装 3.XmlHelper快速操作xml文档 4.Serializatio ...

  5. 七、.net core下配置、数据库访问等操作实现

    配置读取 .net core下读取配置还是有点麻烦的,本身没有System.Configuration.dll,所以在进行配置前需要自行引用Microsoft.Extensions.Configura ...

  6. .NET Core中使用Dapper操作Oracle存储过程最佳实践

    为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为OracleDbType.RefCursor,输出为:ParameterDir ...

  7. NET Core中使用Dapper操作Oracle存储过程

    .NET Core中使用Dapper操作Oracle存储过程最佳实践   为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为Or ...

  8. # .NET Core下操作Git,自动提交代码到

    .NET Core下操作Git,自动提交代码到 转自博客园(阿星Plus) .NET Core 3.0 预览版发布已经好些时日了,博客园也已将其用于生产环境中,可见 .NET Core 日趋成熟 回归 ...

  9. .net core下对于Excel的一些操作及使用

    原文:.net core下对于Excel的一些操作及使用 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.cs ...

  10. net core体系-web应用程序-4asp.net core2.0 项目实战(1)-5项目数据库操作封装操作-EF框架

    EF框架有三种基本的方式:DB First(数据库优先),Model First(模型优先),Code First(代码优先). Entity Framework4.1之前EF支持“Database  ...

随机推荐

  1. vivo 云服务海量数据存储架构演进与实践

    一.写在开头 vivo 云服务提供给用户备份手机上的联系人.短信.便签.书签等数据的能力,底层存储采用 MySQL 数据库进行数据存储. 随着 vivo 云服务业务发展,云服务用户量增长迅速,存储在云 ...

  2. django动态创建表和动态选择实体

    开发有时需要动态创建表,创建完成后需要动态选择model对应的表,该需求如何实现 1.model层   TestBlock为了动态创建表.getBlockModel为了动态选择表 from djang ...

  3. vue学习笔记 十、状态管理基础结构

    系列导航 vue学习笔记 一.环境搭建 vue学习笔记 二.环境搭建+项目创建 vue学习笔记 三.文件和目录结构 vue学习笔记 四.定义组件(组件基本结构) vue学习笔记 五.创建子组件实例 v ...

  4. vue-draggable 学习和使用

    vue-draggable 学习和使用 https://www.jianshu.com/p/e8ff1e1cafb1

  5. df -h与df -i的区别

    一. df命令详解: linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息 -a 全部文件系统列表 -h ...

  6. [转帖]linux内存挂载

    1.主要功能 在linux中,为了提高读写速度,可以将内存挂载到目录,常见的文件格式有tmpfs和ramfs. 2.挂载步骤 $ sudo mkdir /mnt/tmp $ sudo mkdir /m ...

  7. 【转帖】千亿参数大模型首次被撬开!Meta复刻GPT-3“背刺”OpenAI,完整模型权重及训练代码全公布

    https://cloud.tencent.com/developer/article/1991011 千亿级参数AI大模型,竟然真的能获取代码了?! 一觉醒来,AI圈发生了一件轰动的事情-- Met ...

  8. [转帖]配置logback上报日志到Skywalking

    https://zhuanlan.zhihu.com/p/506119895 配置logback上报日志到Skywalking 配置logback上报日志到skywalking需要引入toolkit依 ...

  9. 是否开启raid卡缓存的影响

    开启raid卡缓存 Write back 对IO性能的影响 背景 公司买了一台服务器. 想进行一下升级 但是因为管理员担心数据丢失, 使用了write through + (raid6 + hotsp ...

  10. How to Die ( Since 10.10 )

    以后再也不要相信 sqrt 的精度!对 long long 级别的数取 sqrt 会炸精度! 对于区间差分 \([l,r]\) 的问题,一定要注意是否会出现 \(l>r\) 的情况!(\(|A| ...