DotNetNext / SqlSugar

.Net aot ORM Fastest ORM Simple Easy VB.NET Sqlite orm Oracle ORM Mysql Orm 虚谷数据库 postgresql ORm SqlServer oRm 达梦 ORM 人大金仓 ORM 神通ORM C# ORM , C# ORM .NET ORM NET5 ORM .NET6 ORM ClickHouse orm QuestDb ,TDengine ORM,OceanBase orm,GaussDB orm ,Tidb orm Object/Relational Mapping
https://www.donet5.com/Home/Doc
MIT License
5.24k stars 1.33k forks source link

使用SqlSugarScope,因为注入禁用了委托参数,获取不到指定服务 #1126

Closed MicroHeartWangZheng closed 1 year ago

MicroHeartWangZheng commented 1 year ago

//foreach (var connectionString in connectionStrings)
//{
//    builder.Services.AddScoped<ISqlSugarClient>(serviceProvider => new SqlSugarClient(new ConnectionConfig()
//    {
//        DbType = DbType.MySql,
//        ConnectionString = connectionString,
//        IsAutoCloseConnection = true,
//        ConfigId = connectionString.Contains("Model") ? "Model" : "Basic"
//    },
//    db => db.Aop.OnLogExecuted = (sql, paras) =>
//    {
//        var logger = serviceProvider.GetService<ILogger<SqlSugarClient>>();
//        var eventIdProvider = serviceProvider.GetService<EventIdProvider>();
//        logger.LogInformation($"执行了SQL:EventId:{eventIdProvider.EventId} \r\n sql:{sql} paras:{JsonConvert.SerializeObject(paras)}");
//    }));
//} 
#endregion````

但是使用了  SqlSugarScope,因为注入禁用了委托参数,获取不到指定服务。想要获取Scope类型的服务,导致只能在外面获取,这就导致Scope类型的服务一直是同一个。

````#region SqlSugarScope,每次请求 执行SQL语句中的EventId值固定不变

var serviceProvider = builder.Services.BuildServiceProvider(); 

foreach (var connectionString in connectionStrings)
{
    builder.Services.AddSingleton<ISqlSugarClient>(new SqlSugarScope(new ConnectionConfig()
    {
        DbType = DbType.MySql,
        ConnectionString = connectionString,
        IsAutoCloseConnection = true,
        ConfigId = connectionString.Contains("Model") ? "Model" : "Basic"
    },
    db => db.Aop.OnLogExecuted = (sql, paras) =>
    {
        var logger = serviceProvider.GetService<ILogger<SqlSugarScope>>();
        var eventIdProvider = serviceProvider.GetService<EventIdProvider>();
        //eventIdProvider.EventId 值固定不变, 因为SqlSugarScope不能传委托参数serviceProvider
        logger.LogInformation($"{eventIdProvider.EventId}  sql:{sql} paras:{JsonConvert.SerializeObject(paras)}");
    }));
} 
#endregion````

完整代码示例在 [https://github.com/MicroHeartWangZheng/SS](url)   
DotNetNext commented 1 year ago

提供完整的GITHUB代码

DotNetNext commented 1 year ago

上面的地址无效

MicroHeartWangZheng commented 1 year ago

上面的地址无效

https://github.com/MicroHeartWangZheng/SS

DotNetNext commented 1 year ago

还是无效地址

DotNetNext commented 1 year ago

image

MicroHeartWangZheng commented 1 year ago

还是无效地址

不好意思,设置成私有仓库了,已经改了。还是刚才那个网址

DotNetNext commented 1 year ago

应该改成这样

DotNetNext commented 1 year ago

image

MicroHeartWangZheng commented 1 year ago

image image 我按照图片上修改的 报错了,我调试看了 初始化配置的时候,ConfigId 是“Model”

但是 this.basicClient = sqlSugarClients.AsTenant().GetConnection("Basic"); 这个不报错, 我注释上面的。 image 按道理说 EventIdProvider注入类型是Scope,应该同一个请求参生的 值一样。 是我哪里搞错了吗?

MicroHeartWangZheng commented 1 year ago

image

我这个有两个数据库链接 ,其实不是租户,就是普通的连接两个数据库。

MicroHeartWangZheng commented 1 year ago

应该改成这样

我更新了代码,您可以看看。

MicroHeartWangZheng commented 1 year ago

User表

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;


-- Table structure for User


DROP TABLE IF EXISTS User; CREATE TABLE User ( Id int NOT NULL, Name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (Id) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

MicroHeartWangZheng commented 1 year ago

IkWord表

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;


-- Table structure for IkWord


DROP TABLE IF EXISTS IkWord; CREATE TABLE IkWord ( Id int NOT NULL AUTO_INCREMENT, Word varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, Type int NOT NULL, PRIMARY KEY (Id) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = COMPACT;

SET FOREIGN_KEY_CHECKS = 1;

DotNetNext commented 1 year ago

换成租户注入

DotNetNext commented 1 year ago

var db = new SqlSugarScope(new List() { new ConnectionConfig(){ConfigId="A",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true}, new ConnectionConfig(){ConfigId="B",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true }, new ConnectionConfig(){ConfigId="C",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true } }, db=>{ db.GetConnection("A").Aop.xxx=xxx db.GetConnection("B").Aop.xxx=xxx }); 注入这个对象

MicroHeartWangZheng commented 1 year ago

var db = new SqlSugarScope(new List() { new ConnectionConfig(){ConfigId="A",DbType=DbType.SqlServer,ConnectionString=..,IsAutoCloseConnection=true}, new ConnectionConfig(){ConfigId="B",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true }, new ConnectionConfig(){ConfigId="C",DbType=DbType.MySql,ConnectionString=..,IsAutoCloseConnection=true } }, db=>{ db.GetConnection("A").Aop.xxx=xxx db.GetConnection("B").Aop.xxx=xxx }); 注入这个对象

如果用SqlSugarClient,就没有其他的办法了吗?

DotNetNext commented 1 year ago

一样用法, 就是一个对象扔多个connection,然后用租户 取拿子DB

DotNetNext commented 1 year ago

SqlSugarScope和SqlSugarClient都可以, IOC用 ISqlSugarClient 只不过SqlSugarScope是单例 SqlSugarClient 是Scoped注入 他们注入方式不同

DotNetNext commented 1 year ago

https://www.donet5.com/Home/Doc?typeId=2246 这个是文档推荐这样实现

你那种写法也可以需要改成,不过这样就麻烦了 .AddSingleton<List<ISqlSugarClient>>(List<ISqlSugarClient>)

DotNetNext commented 1 year ago

IOC一般不会注入LIST对象,也不符合逻辑

DotNetNext commented 1 year ago

还有疑问发新的issue这个先关闭了

MicroHeartWangZheng commented 1 year ago

image image 我按照图片上修改的 报错了,我调试看了 初始化配置的时候,ConfigId 是“Model”

但是 this.basicClient = sqlSugarClients.AsTenant().GetConnection("Basic"); 这个不报错, 我注释上面的。 image 按道理说 EventIdProvider注入类型是Scope,应该同一个请求参生的 值一样。 是我哪里搞错了吗?

感觉作者是为了赶紧关闭issues而回答,提的两个问题一个都没解决 ,作者根本就没有用心解决问题。这个框架用了一段时间,真的觉得封装的越来越乱,好像是为了兼容各种功能,没有做好提前规划,而且部分api真的反人类用法。 确实ORM功能很多,很全,按照文档也能实现,但是有些写法真的反人类。 特别想吐槽 多表联查的 SelectAll() ,还有 SqlSugarScope的注入 不能使用委托参数,我是真的不理解。我水平有限,但是这种反人类api,只能去死记硬背,跟微软的的设计格格不入。