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

Aop的事件中注入Scope类型对象,获的值不一致 #1121

Closed MicroHeartWangZheng closed 1 year ago

MicroHeartWangZheng commented 1 year ago

下面是注入多个SqlSugarScope

            foreach (var connectionString in connectionStrings)
            {
                var sqlSuagrConnectionConfig = new ConnectionConfig
                {
                    DbType = DbType.MySql,
                    ConnectionString = connectionString.Value,
                    ConfigId = connectionString.Key,
                    IsAutoCloseConnection = true,
                };

                services.AddSingleton<ISqlSugarClient>(seviceProvider =>
                {
                    sqlSuagrConnectionConfig.AopEvents = new AopEvents()
                    {
                        OnLogExecuted = (sql, paras) =>
                        {
                           //我想在记录日志时,传递一个参数EventId
                            var eventIdProvider = seviceProvider.GetService<EventIdProvider>();
                            var logger = seviceProvider.GetService<ILogger<SqlSugarClient>>();
                            logger.LogInformation($"{eventIdProvider.EventId}   sql:{sql} paras:{JsonConvert.SerializeObject(paras)}");
                        }
                    };
                    return new SqlSugarScope(sqlSuagrConnectionConfig);
                });
            }

下面是EventIdProvider的实现

public class EventIdProvider
    {
        public EventId EventId { get; set; }

        public EventIdProvider()
        {
            string name = DateTime.Now.ToString("yyyyMMddHHmmssfffff") ?? "";
            EventId = new EventId(0, name);
        }
    }

//EventIdProvider 的注入 是Scope类型的

services.AddScoped<EventIdProvider>();

//加了一个Action过滤器 ,问题就在 同一个请求中 过滤器中的EventId值和Aop中的EventId不一致

public class ActionLogFilter : IActionFilter
    {
        private readonly ILogger<ActionLogFilter> logger;

        private readonly EventIdProvider eventIdProvider;

        private readonly ICurrentUserService currentUserService;

        public ActionLogFilter(ILogger<ActionLogFilter> logger, EventIdProvider eventIdProvider, ICurrentUserService currentUserService)
        {
            this.logger = logger;
            this.eventIdProvider = eventIdProvider;
            this.currentUserService = currentUserService;
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            if (context.Exception != null || context.Result is Microsoft.AspNetCore.Mvc.FileStreamResult)
                return;
            logger.LogDebug(eventIdProvider.EventId, $"请求返回:{JsonConvert.SerializeObject(context.Result)}");
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            logger.LogDebug(eventIdProvider.EventId, $"操作人Id:{currentUserService?.User?.Id} \r\n" +
                                                     $"操作人:{currentUserService?.User?.Name}  \r\n" +
                                                     $"请求地址:{context.HttpContext.Request.Path} \r\n" +
                                                     $"请求方式:{context.HttpContext.Request.Method} \r\n" +
                                                     $"请求参数:{JsonConvert.SerializeObject(context.ActionArguments.Values)}");
        }
    }
DotNetNext commented 1 year ago

image AOP应该是在我圈的地方加

DotNetNext commented 1 year ago

services.AddSingleton(seviceProvider => 这个也错的

services.AddSingleton(对象)

DotNetNext commented 1 year ago

image

MicroHeartWangZheng commented 1 year ago
 services.AddScoped<ISqlSugarClient>(serviceProvider => new SqlSugarClient(new ConnectionConfig()
  {
      DbType = DbType.MySql,
      ConnectionString = connectionString.Value,
      ConfigId = connectionString.Key,
      IsAutoCloseConnection = true,
  },
 db => db.Aop.OnLogExecuted = (sql, paras) =>
 {
     var eventIdProvider = serviceProvider.GetService<EventIdProvider>();
     var logger = serviceProvider.GetService<ILogger<SqlSugarClient>>();
     logger.LogInformation($"{eventIdProvider.EventId}   sql:{sql} paras:{JsonConvert.SerializeObject(paras)}");
 }));

我以为是SqlSugarScope 注入类型是单例,而 EventIdProvider注入类型是Scope,单例中注入Scope会有问题导致的。 换成SqlSugarClient 结果也是一样

MicroHeartWangZheng commented 1 year ago

image AOP应该是在我圈的地方加

修改后的注入方式 ,同一请求中,执行SQL的EventId 和 过滤器中的EventId 还是不一样。 前者数值固定不变

       `var seviceProvider = services.BuildServiceProvider();
        var connectionStrings = configuration.GetSection("connectionStrings").GetChildren();
        foreach (var connectionString in connectionStrings)
        {
            var sqlSugarScope = new SqlSugarScope(new ConnectionConfig()
            {
                DbType = DbType.MySql,
                ConnectionString = connectionString.Value,
                ConfigId = connectionString.Key,
                IsAutoCloseConnection = true,
            }, 
            db =>db.Aop.OnLogExecuted = (sql, paras) =>
                {
                    var eventIdProvider = seviceProvider.GetService<EventIdProvider>();
                    var logger = seviceProvider.GetService<ILogger<SqlSugarScope>>();
                   //这里生成的EventId值 固定不变
                    logger.LogInformation($"{eventIdProvider.EventId}   sql:{sql} paras:{JsonConvert.SerializeObject(paras)}");
                });
            services.AddSingleton<ISqlSugarClient>(sqlSugarScope);
        }`
DotNetNext commented 1 year ago

多租户AOP需要 foreach 一下

db.GetConnection(i).Aop.OnLogExecuted

如果用的GetConnectionScope需要换成 (2边一致,用哪个AOP注册哪个) db.GetConnectionScope (i).Aop.OnLogExecuted

DotNetNext commented 1 year ago

还有疑问吗

DotNetNext commented 1 year ago

长期未回复,有疑问发新的issue