Files
zszq-trs/YLErpDAL/DataBase/DbSchema.cs
T
hjhan db95699aa2 feat: 基金管理人取数支持跨环境库名——新增 DbSchema 库名插值,bigdata 连接串指向 96/glms_bigdata
问题: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(数据覆盖问题)
2026-08-28 14:31:30 +08:00

42 lines
2.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 + "`";
});
}
}
}