请教单例模式IOC的单元测试 返回
SqlSugar
沟通中
7
590

悬赏:0 飞吻
我是按照官方的推荐方式进行注册的
public static void RegisterSqlSugar(ServiceCollection serviceCollection) { serviceCollection.AddSingleton<ISqlSugarClient>(p => { var mySqlSetting = new MySqlSetting(config); var db = new SqlSugarScope(new ConnectionConfig() { ConnectionString = mySqlSetting.Value.MySqlConnection, // 替换为你的连接字符串 DbType = DbType.MySql, // 数据库类型 IsAutoCloseConnection = true, // 自动释放数据库 InitKeyType = InitKeyType.Attribute, // 从实体特性读取主键信息 ConfigureExternalServices = new ConfigureExternalServices { DataInfoCacheService = new SugarCache(), //擴展二級緩存 SqlFuncServices = SqlFuncMySql.MySqlFuncExternal(), // 擴展自定義sql方法 }, MoreSettings = new ConnMoreSettings { IsAutoRemoveDataCache = true, DefaultCacheDurationInSeconds = 60 * 10,//默认缓存时间为 10 分钟 DisableMillisecond = true //插入和更新禁用毫秒 }, }); return db; }); }
为了保证万无一失 , 我写了一个这样子的单元测试
private readonly ISqlSugarClient _db; public SqlSugarConcurrentTest() { _db = GetInterface<ISqlSugarClient>(); } [Fact] public async Task Should_Handle_Concurrent_Insert_Correctly() { // Arrange var baseId = Guid.NewGuid().ToString(); var tasks = new List<Task<int>>(); // Act for (int i = 0; i < 10; i++) { var testData = new RolesStaffMappingTable { Id = $"{baseId}-{i}".Right(36), RoleId = Guid.NewGuid().ToString(), StaffId = Guid.NewGuid().ToString(), IsDeleted = false }; tasks.Add(_db.Insertable(testData).ExecuteCommandAsync()); } var results = await Task.WhenAll(tasks); // Assert results.All(r => r == 1).ShouldBeTrue(); var count = await _db.Queryable<RolesStaffMappingTable>() .Where(x => x.Id.StartsWith(baseId)) .CountAsync(); count.ShouldBe(10); }
但是运行到了
var results = await Task.WhenAll(tasks);
就会报以下错误
SqlSugar.SqlSugarException Cannot Open when State is Connecting. at SqlSugar.MySqlProvider.ExecuteCommandAsync(String sql, SugarParameter[] parameters) at SqlSugar.MySqlProvider.ExecuteCommandAsync(String sql, SugarParameter[] parameters) at SqlSugar.InsertableProvider`1.ExecuteCommandAsync() at BTypeWheelsetBoltManagement.IntegrationTests.SqlSugarConcurrentTest.Should_Handle_Concurrent_Insert_Correctly() in F:\Aaron项目\GJCX24001\BTypeWheelsetBoltManagement\BTypeWheelsetBoltManagement.IntegrationTests\SqlSugarConcurrentTest.cs:line 39 at Xunit.Sdk.TestInvoker`1.<>c__DisplayClass48_0.<<InvokeTestMethodAsync>b__1>d.MoveNext() in /_/src/xunit.execution/Sdk/Frameworks/Runners/TestInvoker.cs:line 276 --- End of stack trace from previous location --- at Xunit.Sdk.ExecutionTimer.AggregateAsync(Func`1 asyncAction) in /_/src/xunit.execution/Sdk/Frameworks/ExecutionTimer.cs:line 48 at Xunit.Sdk.ExceptionAggregator.RunAsync(Func`1 code) in /_/src/xunit.core/Sdk/ExceptionAggregator.cs:line 90
请问是测试用例有问题 , 还是注册方式有问题?
热忱回答(7)
-
fate sta VIP0
1周前0 回复 -
Aaron 傲 VIP0
1周前@fate sta:你这个文档写在哪里 ? 我又翻了一遍 ,没有找到 .
0 回复 -
?? VIP0
1周前@Aaron 傲: 一看你就没仔细看
0 回复 -
Aaron 傲 VIP0
1周前@fate sta:我换成了SqlSugarClient 模式 , 但是还是出现
Cannot Open when State
is
Connecting.
以下是注册代码
public static void RegisterSqlSugar(this ServiceCollection serviceCollection) { serviceCollection.AddScoped<ISqlSugarClient>(p => { var db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = mySqlSetting.Value.MySqlConnection, // 替换为你的连接字符串 DbType = DbType.MySql, // 数据库类型 IsAutoCloseConnection = true, // 自动释放数据库 InitKeyType = InitKeyType.Attribute, // 从实体特性读取主键信息 ConfigureExternalServices = new ConfigureExternalServices { DataInfoCacheService = new SugarCache(), //擴展二級緩存 SqlFuncServices = SqlFuncMySql.MySqlFuncExternal(), // 擴展自定義sql方法 }, MoreSettings = new ConnMoreSettings { IsAutoRemoveDataCache = true, DefaultCacheDurationInSeconds = 60 * 10, //默认缓存时间为 10 分钟 DisableMillisecond = true //插入和更新禁用毫秒 }, }); return db; }); }
以下为测试用例
private readonly ISqlSugarClient _db; public SqlSugarConcurrentTest() { _db = GetInterface<ISqlSugarClient>(); } [Fact] public async Task Should_Handle_Concurrent_Insert_Correctly() { // Arrange var tasks = new List<Task<int>>(); var addList = new List<RolesStaffMappingTable>(); // Act for (int i = 0; i < 10; i++) { var testData = new RolesStaffMappingTable { Id = IdHelper.NewGuid7(), RoleId = IdHelper.NewGuid7(), StaffId = IdHelper.NewGuid7(), IsDeleted = false }; addList.Add(testData); tasks.Add(_db.Insertable(testData).ExecuteCommandAsync()); } var results = await Task.WhenAll(tasks); // Assert var idList = addList.Select(p => p.Id).ToList(); var sqlList = await _db.Queryable<RolesStaffMappingTable>() .Where(x => idList.Contains(x.Id)) .ToListAsync(); foreach (var item in addList) { sqlList.Any(p => p.Id == item.Id).ShouldBeTrue(); } }
2025-7-4 10:00
没事了已经了解了 , 也是简单粗暴 , 直接 newCopy , 这种属于代码内的并发需要额外处理 , 给不同的线程分配不同的ORM对象 .
实际上用户的请求并行 , 每请求一次 , 就是一个对象 , 只要是方法本身是异步就行了 , 无需额外的 newCopy
0 回复 -
Aaron 傲 VIP0
1周前@??: 的确是没认真 , 那个 Scope 和 Client , 不仔细看还真看不出来 .
0 回复 -
fate sta VIP0
1周前0 回复 -
遗螽 VIP0
1周前hhh
我一直有个疑惑,SqlSugarClient 和SqlSugarScope 似乎名字应该换一下。
0 回复