之前介绍了基于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. 【驱动】SPI驱动分析(五)-模拟SPI驱动

    简介 模拟SPI驱动是一种软件实现的SPI总线驱动.在没有硬件SPI控制器的系统中,通过软件模拟实现SPI总线的功能.它允许在不修改硬件的情况下,通过GPIO(通用输入/输出)引脚模拟SPI总线的通信 ...

  2. 30 秒使用 Sealos 搭建个人密码管理器 Vaultwarden

    我与 LastPass 的曲折恋情 超过 8 年网龄的我,注册过很多网站帐号,每个网站的密码我都用不同的复杂密码.一开始我全靠脑力记忆这些密码,后来渐渐觉得记起来很困难,就记录在笔记本上.但是随着时间 ...

  3. Verdi基础-01

    Verdi使用目标 生成fsdb波形 查看fsdb波形 追踪RTL代码 目录 Verdi历史 生成fsdb波形 三个变量&&三个命令 变量PATH LD_LIBRARY_PATH so ...

  4. text, data and bss: Code and Data Size Explained

    [来源]

  5. Laravel : Eloquent 新增

             public function ormCreate()     {         #  1. 使用模型新增 ->save()         /*               ...

  6. [转帖]技术分享| MySQL 的 AWR Report?— MySQL 状态诊断报告

    https://segmentfault.com/a/1190000039959767     作者:秦福朗 爱可生 DBA 团队成员,负责项目日常问题处理及公司平台问题排查.热爱 IT,喜欢在互联网 ...

  7. [转帖]如何通过JMeter测试金仓数据库KingbaseES并搭建环境

    1.安装JMeter Apache JMeter是Apache组织开发的基于Java的压力测试工具,主要用于对软件的压力测试,它最初被设计用于Web应用测试,但后来扩展到其它测试领域.它可测试静态.动 ...

  8. isolcpus的学习与了解

    isolcpus的学习与了解 前言 最近一直跟同事说要进行CPU的bind bind到具体的core 当时还一直装B, 说这样能够提高性能. 但是今天起床早上查看资料时发现,其实是先设置隔离的. 让操 ...

  9. gcore的学习

    gcore的学习-解决jmap无法生成dump文件的一种方法 背景 周末在跆拳道馆看孩子练跆拳道. 开着笔记本翻到了 扣钉日记 公众号里面的讲解 想着自己也遇到过无法保存dump文件的情况. 所以想学 ...

  10. [转帖]Docker、containerd的关系

    Docker.containerd的关系 containerd囊括了单机运行一个容器时所需要的一切: 为了能够支持多种OCI Runtime,containerd 内部使用containerd-shi ...