.net5 EFCore 封装读写分离
要求:分数据库和主从库,
直接上代码
"DbConnect": {
"DateBaseType": "sql", //sql,oracle,mysql
"ReadConnectionString": [
"Data Source=DESKTOP-23DM9NS;Initial Catalog=ExcellentCode; User Id=tudawei;Password=tudawei"
],
"WriteConnectionString": "Data Source=DESKTOP-23DM9NS;Initial Catalog=ExcellentCode; User Id=tudawei;Password=tudawei"
},
public class DbConntection
{
/// <summary>
/// 数据库类型
/// </summary>
public DateBaseType DateBaseType { set; get; }
/// <summary>
/// 读数据库
/// </summary>
public List<string> ReadConnectionString { get; set; }
/// <summary>
/// 写数据库
/// </summary>
public string WriteConnectionString { get; set; }
}
services.Configure<DbConntection>(Configuration.GetSection(AppSettingConst.DbConnect));//appsetting映射到实体
//services.AddTransient<IDateContext, DapperContext>();
services.AddTransient<IDateContext, BaseDateContext>();
public interface IDateContext
{
DbContext CreateEF(ReadOrWrite readOrWrite);
}
public class BaseDateContext: IDateContext
{
private readonly IOptions<DbConntection> _options = null;
private IDbConnection _idbConntection = null;
public BaseDateContext(IOptions<DbConntection> options, IDbConnection idbConntection)
{
_options = options;
_idbConntection=idbConntection;
}
protected string CreateDb(ReadOrWrite readOrWrite)
{
string strConnString = string.Empty;
switch (readOrWrite)
{
case Enum.ReadOrWrite.Read:
strConnString = Dispatcher(_options.Value.ReadConnectionString);
break;
case Enum.ReadOrWrite.Write:
strConnString = _options.Value.WriteConnectionString;
break;
default:
break;
}
return strConnString;
}
public DbContext CreateEF(ReadOrWrite readOrWrite)
{
//这一段代码有待优化,不应该出现NEW的情况,可以改成注入
EFContext db = new EFContext();
return db.ToWriteOrRead(CreateDb(readOrWrite), _options);
}
/// <summary>
/// 调度分配--随机就是平均
/// </summary>
/// <param name="connectionStrings"></param>
/// <returns></returns>
private string Dispatcher(List<string> connectionStrings)
{
int _Seed = 0;
string conn = connectionStrings[_Seed++ % connectionStrings.Count];//轮询--seed需要线程安全
return conn;
}
}
public class EFContext : DbContext
{
public string Conn = null;
private IOptions<DbConntection> _options = null;
public DbContext ToWriteOrRead(string conn, IOptions<DbConntection> options)
{
Conn = conn;
_options = options;
return this;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder)
{
switch (_options.Value.DateBaseType)
{
case Enum.DateBaseType.oracle:
optionBuilder.UseOracle(Conn);
break;
case Enum.DateBaseType.mysql:
break;
case Enum.DateBaseType.sql:
optionBuilder.UseSqlServer(Conn);
break;
default:
break;
}
}
public DbSet<User> User { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//base.OnModelCreating(modelBuilder);
modelBuilder.AutoMapperApply();
//modelBuilder.ApplyConfiguration(new UserMap());
// Interface that all of our Entity maps implement
}
}
以上可以完成读写分离的操作,代码有待优化,尤其是在