问题:SQL 硬编码物理库名(bigdata./glms_bigdata.),关联库在不同环境库名不同,换环境即失效;
且仓库所有 appsettings 均未配 bigdata 连接串,本地/单测环境一直走 Unavailable 降级。
- 新增 YLErpDAL/DataBase/DbSchema:从连接串 database= 解析物理库名(含反引号、\w+ 白名单校验、进程级缓存),
跨库 SQL 写 DbSchema.Of("bigdata").mf_fundarchives ——代码只认逻辑连接名(等价 Java @Mapper 指定数据源),
物理库名归各环境 appsettings;将来 join ERP 主库用 DbSchema.Of("ylcms") 同法插值
- FundManagerLookupService:SQL 两处库名前缀改为插值(查找逻辑/CONVERT/COLLATE 不变),Unavailable 降级语义不变
- appsettings.local.json / UnitTestProject appsettings.json 补 bigdata=192.168.2.96:3306/glms_bigdata(抄现有 96 库连接串改库名)
- 新增 FundManagerLookupServiceTest(连 96 实库):DbSchema 解析断言 + Lookup 连通性
实测 511160.SH → Unique「东财基金管理有限公司」全链路打通;161210/630006 因 mf_investadvisoroutline 仅2行无映射返回 NotFound(数据覆盖问题)
42 lines
2.1 KiB
C#
42 lines
2.1 KiB
C#
using MySqlConnector;
|
||
using System.Collections.Concurrent;
|
||
using System.Text.RegularExpressions;
|
||
|
||
namespace YLErp.BLL
|
||
{
|
||
/// <summary>
|
||
/// 跨库 SQL 的物理库名解析器:代码里只写逻辑连接名(appsettings ConnectionStrings 的 key,
|
||
/// 与 Java @Mapper 指定数据源名同语义),物理库名由各环境连接串的 database= 决定——
|
||
/// 同一逻辑库在不同环境库名不同(如 bigdata 在测试环境为 glms_bigdata),SQL 中硬编码库名会跨环境失败。
|
||
/// 用法:{@DbSchema.Of("bigdata")}.mf_fundarchives(返回带反引号的库名,可直接内插)。
|
||
/// 仅标识自家的 appsettings 连接串,值不来自用户输入;仍做 \w+ 白名单校验防御配置笔误。
|
||
/// </summary>
|
||
public static class DbSchema
|
||
{
|
||
private static readonly ConcurrentDictionary<string, string> Cache = new();
|
||
private static readonly Regex SafeIdentifier = new(@"^\w+$", RegexOptions.Compiled);
|
||
|
||
/// <summary>
|
||
/// 取逻辑连接名对应的物理库名(形如 `glms_bigdata`,含反引号)。配置缺失或库名非法立即抛错——
|
||
/// 跨库 SQL 拼错库名在运行期才暴露更难排查,配置错误应尽早失败。
|
||
/// </summary>
|
||
public static string Of(string connectionKey)
|
||
{
|
||
return Cache.GetOrAdd(connectionKey, key =>
|
||
{
|
||
var connectionString = AppManager.GetConnectionString(key);
|
||
if (string.IsNullOrWhiteSpace(connectionString))
|
||
{
|
||
throw new InvalidOperationException($"跨库SQL依赖的连接串未配置:{key}");
|
||
}
|
||
var database = new MySqlConnectionStringBuilder(connectionString).Database;
|
||
if (string.IsNullOrWhiteSpace(database) || !SafeIdentifier.IsMatch(database))
|
||
{
|
||
throw new InvalidOperationException($"连接串 {key} 缺少 database 或库名非法:{database}");
|
||
}
|
||
return "`" + database + "`";
|
||
});
|
||
}
|
||
}
|
||
}
|