前置条件
MySQL 主从复制:https://www.cnblogs.com/fallTakeMan/p/14038888.html
环境说明
本机开发环境:Win10,VS2019,.NetCoreSDK 3.1
MySQL 服务器:192.168.187.66:3306(写),192.168.187.66:3307(读)
项目结构
一个 webapi 项目,两个 dotnetcore 类库项目,ftm.EFcore 引用 ftm.Entity,ftm.api 引用 ftm.EFcore。
项目说明
ftm.EFcore 项目引用 nuget 包 Microsoft.EntityFrameworkCore(3.1.1),MySql.Data.EntityFrameworkCore(8.0.22)。
创建三个文件 AppDbContext,IDbContextFactory,DbContextFactory。
1 using ftm.Entity; 2 using Microsoft.EntityFrameworkCore; 3 4 5 namespace ftm.EFcore 6 { 7 public class AppDbContext : DbContext 8 { 9 private string connString = string.Empty; 10 /// <summary> 11 /// 传入数据库链接字符串构造 AppDbContext 12 /// </summary> 13 /// <param name="conn">数据库链接字符串</param> 14 public AppDbContext(string conn) 15 { 16 connString = conn; 17 } 18 19 public DbSet<User> User { get; set; } 20 21 protected override void OnConfiguring(DbContextOptionsBuilder options) 22 { 23 options.UseMySQL(connString); 24 } 25 26 protected override void OnModelCreating(ModelBuilder builder) 27 { 28 builder.Entity<User>().HasKey(x => x.Id); 29 } 30 } 31 }
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace ftm.EFcore 6 { 7 /// <summary> 8 /// DbContext 工厂 9 /// </summary> 10 public interface IDbContextFactory 11 { 12 public AppDbContext CreateDbContext(DbContextType contextType); 13 } 14 /// <summary> 15 /// 读写类型 16 /// </summary> 17 public enum DbContextType 18 { 19 Write, 20 Read 21 } 22 }
1 using Microsoft.Extensions.Configuration; 2 using System; 3 using System.Collections.Generic; 4 using System.Text; 5 6 namespace ftm.EFcore 7 { 8 /// <summary> 9 /// DbContext 工厂 10 /// </summary> 11 public class DbContextFactory : IDbContextFactory 12 { 13 private IConfiguration _configuration; 14 private string[] _readConn; 15 /// <summary> 16 /// 传入配置接口构造 DbContextFactory 17 /// </summary> 18 /// <param name="configuration">配置项接口</param> 19 public DbContextFactory(IConfiguration configuration) 20 { 21 _configuration = configuration; 22 _readConn = _configuration["ConnectionString:ReadConnStr"].Split(","); 23 } 24 public AppDbContext CreateDbContext(DbContextType contextType) 25 { 26 string connStr = string.Empty; 27 switch (contextType) 28 { 29 case DbContextType.Write: 30 connStr = _configuration["ConnectionString:WriteConnStr"]; 31 break; 32 case DbContextType.Read: 33 connStr = GetReadConn(); 34 break; 35 36 } 37 return new AppDbContext(connStr); 38 } 39 /// <summary> 40 /// 获取读库链接字符串 41 /// </summary> 42 /// <remarks> 43 /// TODO:根据不同策略获取链接字符串 44 /// </remarks> 45 /// <returns>读库链接字符串</returns> 46 private string GetReadConn() 47 { 48 // 读库策略 49 50 int index = new Random().Next(0, _readConn.Length - 1); 51 return _readConn[index]; 52 } 53 } 54 }
ftm.api 项目配置数据库链接字符串。
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ConnectionString": { "WriteConnStr": "Server=192.168.187.66;port=3306;database=test_db;uid=root;pwd=root", "ReadConnStr": "Server=192.168.187.66;port=3307;database=test_db;uid=root;pwd=root" } }
Startup 中注入 DbContextFactory。
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddScoped<IDbContextFactory, DbContextFactory>(); services.AddControllers(); }
在 ftm.api 项目中应用读写分离。
查看 MySQL 主库和从库,User 表和数据同步。