让Dapper在一个项目中支持多种库

DotNetCore实战

共 6490字,需浏览 13分钟

 ·

2021-05-30 13:15


如果想在一个项目中,用DapperPlus支持多种数据库该怎么做?

在《让Dapper支持Mock》中我们定义了DapperPlus,可以基于这个类,实现两个子类:MySqlDapperPlus,MsSqlDapperPls,在这两个子类的构造中适配对应的数据库类型,从注放容器中,获取IDbConnection实例,根据实例的类型来选取配置中的对应连接字符串,这里用到的是根据数据类型来配置,也是一种约定。


MySqlDapperPlus.cs

using Microsoft.Extensions.Configuration;using System;using System.Collections.Generic;using System.Data;using System.Linq;
namespace WebDemo01.Services{ public class MySqlDapperPlus : DapperPlus { public MySqlDapperPlus(IEnumerable<IDbConnection> connections, IConfiguration configuration) { var connectionStrings = configuration.GetSection("ConnectionStrings").Get<Dictionary<string, string>>(); _connection = connections.FirstOrDefault(c => c.GetType().Name == "MySqlConnection"); _connection.ConnectionString = connectionStrings.Where(s => s.Key.ToLower().Contains("mysql")).FirstOrDefault().Value; } }}

MsSqlDapperPlus.cs

using Microsoft.Extensions.Configuration;using System;using System.Collections.Generic;using System.Data;using System.Linq;
namespace WebDemo01.Services{ public class MsSqlDapperPlus : DapperPlus { public MsSqlDapperPlus(IEnumerable<IDbConnection> connections, IConfiguration configuration) { var connectionStrings = configuration.GetSection("ConnectionStrings").Get<Dictionary<string, string>>(); _connection = connections.FirstOrDefault(c => c.GetType().Name == "SqlConnection"); _connection.ConnectionString = connectionStrings.Where(s => s.Key.ToLower().Contains("mssql")).FirstOrDefault().Value; } }}

这时,会有问题,DapperPlus没有无参构造,_connection访问级别也太低,所以要改造一下DapperPlus。

    /// <summary>    /// DappePlusr类    /// </summary>    public class DapperPlus : IDapperPlus    {        protected IDbConnection _connection;        /// <summary>        /// 无参构造函数        /// </summary>        public DapperPlus()        {        }        //下面和原来的一样    }


public void ConfigureServices(IServiceCollection services){        services.AddControllers();                    services.AddScoped<IDbConnection, MySqlConnection>();        services.AddScoped<IDbConnection, SqlConnection>();        services.AddScoped<IDapperPlus, MySqlDapperPlus>();        services.AddScoped<IDapperPlus, MsSqlDapperPlus>();}

appsettings.json

  "ConnectionStrings": {    "MySqlConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=mysql_testdb",    "MsSqlConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=mssql_testdb"  }




如果是多个库,还要读写分离该怎么实现?其实和不分离是一样的,要改造《让Dapper读写分离》中的DapperPlusWrite和DapperPlusRead两个类,分别增加无参构造函数,和把_connection改成protected,方便子类中参访问到。

然后定义三个类:MySqlDapperPlusRead和MsSqlDapperPlusRead继承DapperPlusRead;MySqlDapperPlusWrite和MsSqlDapperPlusWrite继承DapperPlusWrite。在四个类的构造函数中,按照自己数据库的类型,Read或Write类型来取配置文件中的连接字符串即可。

Startup.cs

public void ConfigureServices(IServiceCollection services){      services.AddControllers();      services.AddScoped<IDbConnection, MySqlConnection>();      services.AddScoped<IDbConnection, SqlConnection>();      services.AddScoped<IDapperPlusRead, MySqlDapperPlusRead>();      services.AddScoped<IDapperPlusRead, MsSqlDapperPlusRead>();      services.AddScoped<IDapperPlusWrite, MySqlDapperPlusWrite>();      services.AddScoped<IDapperPlusWrite, MsSqlDapperPlusWrite>();}

appsettings.json

  "ConnectionStrings": {    "MySqlReadConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=read_mysql_testdb",    "MySqlWriteConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=write_mysql_testdb",    "MsSqlReadConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=read_mssql_testdb",    "MsSqlWriteConnectionString": "server=127.0.0.1;uid=root;pwd=root;database=write_mssql_testdb"  }

最后,在业务的Service中,读有两个,按类型区分,写有两个,按类型区分,代码如下:

    public class GoodsService : IGoodsService    {        private readonly IDapperPlusWrite _mySqlDapperWrite;        private readonly IDapperPlusWrite _msSqlDapperWrite;        private readonly IDapperPlusRead _mySqlDapperRead;        private readonly IDapperPlusRead _msSqlDapperRead;        public ShopService(IEnumerable<IDapperPlusWrite> dapperWrites, IEnumerable<IDapperPlusRead> dapperReads)        {            foreach (var dapperWrite in dapperWrites)            {                switch (dapperWrite)                {                    case MySqlDapperPlusWrite mySqlDapperPlusWrite:                        _mySqlDapperWrite = mySqlDapperPlusWrite;                        break;                    case MsSqlDapperPlusWrite msSqlDapperPlusWrite:                        _msSqlDapperWrite = msSqlDapperPlusWrite;                        break;                }            }            foreach (var dapperRead in dapperReads)            {                switch (dapperRead)                {                    case MySqlDapperPlusRead mySqlDapperPlusRead:                        _mySqlDapperRead = mySqlDapperPlusRead;                        break;                    case MsSqlDapperPlusRead msSqlDapperPlusRead:                        _msSqlDapperRead = msSqlDapperPlusRead;                        break;                }
} }    }



往期精彩回顾




【推荐】.NET Core开发实战视频课程 ★★★

.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划

【.NET Core微服务实战-统一身份认证】开篇及目录索引

Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)

.NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

10个小技巧助您写出高性能的ASP.NET Core代码

用abp vNext快速开发Quartz.NET定时任务管理界面

在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度

现身说法:实际业务出发分析百亿数据量下的多表查询优化

关于C#异步编程你应该了解的几点建议

C#异步编程看这篇就够了


浏览 16
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报