SqlSugarClient 模式 IOC方式实现线程安全 返回
1、SqlSugarClient通过AddScoped注入 (注意 SqlSugarClient才能这么用)
2、代码如下
public class MyProcessor
{
private readonly IServiceScopeFactory _scopeFactory;
public MyProcessor(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task ProcessBatchAsync(List<int> ids)
{
var tasks = ids.Select(async id =>
{
using var scope = _scopeFactory.CreateScope();
var myService = scope.ServiceProvider.GetRequiredService<IMyBusinessService>();
// 同一个 scope 内 db 上下文是同一个对象
await myService.ProcessAsync1(id);
await myService.ProcessAsync2(id);
});
await Task.WhenAll(tasks);
}
}
热忱回答(11)
-
fate sta VIP0
2025/6/5正确用法
//注册上下文:AOP里面可以获取IOC对象,如果有现成框架比如Furion可以不写这一行 services.AddHttpContextAccessor(); //注册SqlSugar用AddScoped services.AddScoped<ISqlSugarClient>(s => { //Scoped用SqlSugarClient SqlSugarClient sqlSugar = new SqlSugarClient (new ConnectionConfig() { DbType = SqlSugar.DbType.Sqlite, ConnectionString = "DataSource=sqlsugar-dev.db", IsAutoCloseConnection = true, }, db => { //每次上下文都会执行 //获取IOC对象不要求在一个上下文 //var log=s.GetService<Log>() //获取IOC对象要求在一个上下文 //var appServive = s.GetService<IHttpContextAccessor>(); //var log= appServive?.HttpContext?.RequestServices.GetService<Log>(); db.Aop.OnLogExecuting = (sql, pars) => { }; }); return sqlSugar; });注意点:
services.AddScoped<ISqlSugarClient>(SqlSugarClient变量)//这种用法错误 services.AddScoped<ISqlSugarClient>(s => SqlSugarClient变量)//这种用法错误 services.AddScoped<ISqlSugarClient>(s => new SqlSugarScope ..)//这种用法错误 services.AddScoped<ISqlSugarClient>(s =>new SqlSugarClient.. )//正确
建议直接复制我写的。这样100% OK
0 回复 -
Leckun VIP0
2025/6/24repository怎么弄?
0 回复 -
fate sta VIP0
2025/6/24@Leckun:
usingvarscope = _serviceProvider.CreateScope();varmyService = scope.ServiceProvider.GetRequiredService<仓储>();0 回复 -
winnyrain VIP0
2025/7/23当定时任务里还有一层Task的时候,IServiceProvider经常会出现Cannot access a disposed object,后查资料发现IServiceProvider分父容器和子容器,注入创建的是子容器的IServiceProvider,当父容器的因异步调用立即返回后,父容器相关的会被释放,导致这个问题发生。
后来改用IServiceScopeFactory问题解决。
0 回复 -
fate sta VIP0
2025/8/13@winnyrain:用例改成了IServiceScopeFactory
0 回复 -
mousd VIP0
2025/9/3请问如果存在多个db连接,需要如何配置ioc注入呢
0 回复 -
心然 VIP0
2周前请教一下,以下代码结构,支持多个不同数据库(oracle,postgre,sqlserver)连接方式是否正确?或者有什么建议,感谢!
private static SqlSugarScope _dbs;
/// <summary>
/// SqlSugar 数据库实例
/// </summary>
public static SqlSugarScope Dbs
{
get {
if (_dbs == null)
{
try
{
// 读取 appsettings.json 中的 ConnectionConfigs 配置节点(多个数据库连接字符串)
_dbs = new SqlSugarScope(ConnectionConfigs,
db =>
{
//配置全局事件
ConfigureAopEvents(db);
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to initialize SqlSugarScope.");
throw;
}
}
return _dbs;
}
}
private static ISqlSugarClient _dbERP;
/// <summary>
/// ERP系统数据库实例
/// </summary>
public static ISqlSugarClient DbERP
{
get
{
if (_dbERP == null)
{
try
{
_dbERP = Dbs.GetConnection(ConfigId_ERP);
// 为该连接单独配置 AOP 事件
ConfigureAopEvents(_dbERP);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get connection for ERP.");
throw;
}
}
return _dbERP;
}
}
private static ISqlSugarClient _dbOA;
/// <summary>
/// ERP系统数据库实例
/// </summary>
public static ISqlSugarClient DbOA
{
get
{
if (_dbOA == null)
{
try
{
_dbOA = Dbs.GetConnection(ConfigId_OA);
// 为该连接单独配置 AOP 事件
ConfigureAopEvents(_dbOA);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get connection for OA.");
throw;
}
}
return _dbOA;
}
}
//通用服务类注入SqlSugarClient
public class GenericService<T> : IGenericService<T> where T : class, new()
{
private readonly ISqlSugarClient _db;
private readonly IMemoryCache _cache;
public GenericService(ISqlSugarClient db, IMemoryCache cache)
{
_db = db;
_cache = cache;
}
/// <summary>
/// 添加记录
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public bool Insert(T entity)
{
return _db.Insertable<T>(entity).ExecuteCommand() > 0;
}
}
/// <summary>
/// SqlSugar数据库访问器
/// </summary>
public class DatabaseAccessor : IDatabaseAccessor
{
public ISqlSugarClient OA => DbContext.DbOA;
public ISqlSugarClient ERP => DbContext.DbERP;
}
//具体对象服务类继承通用服务类,通过数据库访问器进行注入数据库SqlSugarClient
public class UserService : GenericService<User>, IUserService, ITransient
{
private readonly IDatabaseAccessor _db;
private readonly IMemoryCache _cache;
public UserService(IDatabaseAccessor db, IMemoryCache cache):base(db.APS,cache)
{
_db = db;
_cache = cache;
}
}
0 回复 -
海绵宝宝 VIP0
1天前我使用IOC注册,使用方法跟您一样:

但是还有错误,有2种错误(但猜测其实是同一种):
System.InvalidOperationException: 此连接不支持 MultipleActiveResultSets。
System.InvalidOperationException: 已有打开的与此 Connection 相关联的 DataReader,必须首先将它关闭。
官网说这个方法偶发很低,但是我本地跑项目(前端vue+netcore webAPI),实测偶发很高,2-4次就发生一次。
0 回复 -
fate sta VIP0
1天前@海绵宝宝:注册没有问题,关键是不是有用的地方有问题
0 回复 -
fate sta VIP0
1天前报错代码强制一下线程安全
usingvarscope = _scopeFactory.CreateScope();varmyService = scope.ServiceProvider.GetRequiredService<IMyBusinessService>();//也可以是ISqlSugarClient0 回复 -
fate sta VIP0
1天前@mousd:文档: new sqlsugraclient(configList) 多个传LSIT,文档:多租户有用法介绍
0 回复