#! MySQL先配置主从复制,可参照主从复制
1. 在appsettings.json中增加以下配置。
"ConnectionStrings": {
"Default": "Server=localhost;Port=3307;Database=数据库名称;Uid=root;Pwd=密码;",
"ReadDb": "Server=localhost;Port=3308;Database=数据库名称;Uid=root;Pwd=密码;"
}
2. 在Application层增加CustomActionFilterAttribute.cs文件
// ActionFilterAttribute命名空间:Microsoft.AspNetCore.Mvc.Filters
public class CustomActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
// 确保ActionDescriptor是ControllerActionDescriptor的实例
if (context.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
// 获取控制器动作方法的MethodInfo
MethodInfo methodInfo = controllerActionDescriptor.MethodInfo;
// 检查方法上是否存在[ReadOnly(true)]属性
var readOnlyAttribute = methodInfo.GetCustomAttributes(typeof(ReadOnlyAttribute), false)
.Cast<ReadOnlyAttribute>()
.FirstOrDefault();
if (readOnlyAttribute != null && readOnlyAttribute.IsReadOnly)
{
// 设置一个标记,表明这是一个只读操作
// 你可以将标记存储在HttpContext中,以便后续使用
context.HttpContext.Items["IsReadOnlyOperation"] = true;
// 也可以在这里执行其他逻辑,比如改变数据库连接等
// 但请注意,直接在这里改变数据库连接可能不是最佳实践
// 通常,你会在服务层中根据这个标记来决定使用哪个数据库连接
}
}
}
}
3. 在EntityFrameworkCore层增加DbConnectionStringResolver.cs文件
public class DbConnectionStringResolver : IConnectionStringResolver, ITransientDependency
{
private readonly IConfiguration _configuration;
private readonly IHttpContextAccessor _httpContextAccessor;
public DbConnectionStringResolver(IConfiguration configuration, IHttpContextAccessor httpContextAccessor)
{
_configuration = configuration;
_httpContextAccessor = httpContextAccessor;
}
public string Resolve(string? connectionStringName = null)
{
bool isRead = false;
// 检查HttpContext是否可用
if (_httpContextAccessor.HttpContext != null && _httpContextAccessor.HttpContext.Items.ContainsKey("IsReadOnlyOperation"))
{
var isReadOnly = (bool)_httpContextAccessor.HttpContext.Items["IsReadOnlyOperation"];
if (isReadOnly) isRead = true;
}
string? connectionString = string.Empty;
if (isRead) connectionString = _configuration.GetConnectionString("ReadDb");
else connectionString = _configuration.GetConnectionString("Default");
return connectionString != null ? connectionString : string.Empty;
}
public Task<string> ResolveAsync(string? connectionStringName = null)
{
return Task.FromResult(Resolve(connectionStringName));
}
}
4. 在EntityFrameworkCore层新增ManagementModule.cs文件
[DependsOn(typeof(AbpTenantManagementEntityFrameworkCoreModule))]
public class ManagementModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Replace(ServiceDescriptor.Transient<IConnectionStringResolver, DbConnectionStringResolver>());
context.Services.AddDbContext<ManagerDbContext>((serviceProvider, options) =>
{
var connectionString = serviceProvider.GetRequiredService<IConnectionStringResolver>().Resolve("Default");
options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString));
});
}
}
5. 在Application层对应只读方法增加以下配置
[ReadOnly(true)]
[CustomActionFilter]
public Task<PagedResultDto<Dto>> GetListAsync(GetInput input)
{
// 方法执行
}
# 设置好上述即可。
1461

被折叠的 条评论
为什么被折叠?



