From dc50dfc917cd3d03b41152d226233c44d69d14d2 Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Wed, 25 Mar 2026 02:42:26 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8C=BA=E5=88=86=20SqlSugarScope=20?= =?UTF-8?q?=E5=92=8C=20SqlSugarClient=20=E4=BD=BF=E7=94=A8=E5=9C=BA?= =?UTF-8?q?=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 区分: - GetSqlSugarScope(): 返回 SqlSugarScope,用于 DI 注入(Singleton) - GetSqlSugarClient(): 返回 SqlSugarClient,用于后台任务(每次创建新实例) 原因: - SqlSugarScope 使用 AsyncLocal 隔离上下文 - Task.Run 后台线程中 AsyncLocal 可能无法正确传递 - 后台任务使用 SqlSugarClient 更安全,每个实例独立连接 使用: - DI 注入:GetSqlSugarScope() - Repository 后台写入:GetSqlSugarClient() - MySQL 连接池复用底层 TCP 连接,性能开销小 --- AssetManager.Data/DatabaseExtensions.cs | 2 +- AssetManager.Data/SqlSugarConfig.cs | 89 ++++++++++++++++++------- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/AssetManager.Data/DatabaseExtensions.cs b/AssetManager.Data/DatabaseExtensions.cs index 3a0cf3c..c8af1a3 100755 --- a/AssetManager.Data/DatabaseExtensions.cs +++ b/AssetManager.Data/DatabaseExtensions.cs @@ -12,7 +12,7 @@ public static class DatabaseExtensions // 使用 Singleton 注册,整个应用共享一个实例 services.AddSingleton(s => { - return SqlSugarConfig.GetSqlSugarClient(); + return SqlSugarConfig.GetSqlSugarScope(); }); services.AddScoped(); diff --git a/AssetManager.Data/SqlSugarConfig.cs b/AssetManager.Data/SqlSugarConfig.cs index 319c56e..2a54873 100755 --- a/AssetManager.Data/SqlSugarConfig.cs +++ b/AssetManager.Data/SqlSugarConfig.cs @@ -15,6 +15,9 @@ public static class SqlSugarConfig _configuration = configuration; } + /// + /// 获取 SqlSugarClient 实例(用于后台任务,每次创建新实例) + /// public static ISqlSugarClient GetSqlSugarClient() { if (_configuration == null) @@ -22,36 +25,41 @@ public static class SqlSugarConfig throw new InvalidOperationException("SqlSugarConfig has not been initialized. Call Initialize() first."); } - // 优先从环境变量读取连接字符串 - var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings__Default") - ?? _configuration.GetConnectionString("Default") - ?? throw new InvalidOperationException("Connection string 'Default' not found in environment variables or configuration."); + var connectionString = GetConnectionString(); - // MySQL 连接池优化配置 - // 添加连接池参数提高稳定性 - if (!connectionString.Contains("Pooling=", StringComparison.OrdinalIgnoreCase)) + // 使用 SqlSugarClient(非 Scope),每次创建独立实例 + // 适合后台任务、Task.Run 场景 + return new SqlSugarClient(new ConnectionConfig() { - connectionString += ";Pooling=true"; - } - if (!connectionString.Contains("MaximumPoolSize=", StringComparison.OrdinalIgnoreCase)) + ConnectionString = connectionString, + DbType = DbType.MySql, + IsAutoCloseConnection = true, + InitKeyType = InitKeyType.Attribute, + ConfigureExternalServices = new ConfigureExternalServices + { + EntityService = (property, column) => + { + if (property.PropertyType == typeof(DateTime)) + { + column.DataType = "datetime(3)"; + } + } + } + }); + } + + /// + /// 获取 SqlSugarScope 实例(用于 DI 注入,Singleton/Scoped) + /// + public static ISqlSugarClient GetSqlSugarScope() + { + if (_configuration == null) { - connectionString += ";MaximumPoolSize=100"; - } - if (!connectionString.Contains("MinimumPoolSize=", StringComparison.OrdinalIgnoreCase)) - { - connectionString += ";MinimumPoolSize=5"; - } - // 连接超时和生命周期 - if (!connectionString.Contains("ConnectionTimeout=", StringComparison.OrdinalIgnoreCase)) - { - connectionString += ";ConnectionTimeout=30"; - } - // 连接空闲超时,避免使用长时间空闲的连接 - if (!connectionString.Contains("ConnectionIdleTimeout=", StringComparison.OrdinalIgnoreCase)) - { - connectionString += ";ConnectionIdleTimeout=180"; + throw new InvalidOperationException("SqlSugarConfig has not been initialized. Call Initialize() first."); } + var connectionString = GetConnectionString(); + return new SqlSugarScope(new ConnectionConfig() { ConnectionString = connectionString, @@ -70,4 +78,35 @@ public static class SqlSugarConfig } }); } + + private static string GetConnectionString() + { + var connectionString = Environment.GetEnvironmentVariable("ConnectionStrings__Default") + ?? _configuration!.GetConnectionString("Default") + ?? throw new InvalidOperationException("Connection string 'Default' not found in environment variables or configuration."); + + // MySQL 连接池优化配置 + if (!connectionString.Contains("Pooling=", StringComparison.OrdinalIgnoreCase)) + { + connectionString += ";Pooling=true"; + } + if (!connectionString.Contains("MaximumPoolSize=", StringComparison.OrdinalIgnoreCase)) + { + connectionString += ";MaximumPoolSize=100"; + } + if (!connectionString.Contains("MinimumPoolSize=", StringComparison.OrdinalIgnoreCase)) + { + connectionString += ";MinimumPoolSize=5"; + } + if (!connectionString.Contains("ConnectionTimeout=", StringComparison.OrdinalIgnoreCase)) + { + connectionString += ";ConnectionTimeout=30"; + } + if (!connectionString.Contains("ConnectionIdleTimeout=", StringComparison.OrdinalIgnoreCase)) + { + connectionString += ";ConnectionIdleTimeout=180"; + } + + return connectionString; + } }