程序运行过程中经常报错,This MySqlConnection is already in use 返回

SqlSugar 处理完成
6 249

程序运行过程中经常报错 :This MySqlConnection is already in use

数据库连接配置数据库配置.png

SqlSugar配置注入配置

SQLsugar注入.png

仓储代码

using CloudPlatform.Common.Consts;
using CloudPlatform.Data.Abstractions.Attributes;
using CloudPlatform.Entitys.Style.Tenant;
using CloudPlatform.ORM.Query;
using CloudPlatform.SQL.Abstractions;
using CloudPlatform.SQL.Abstractions.Query;
using SqlSugar;
using System.Linq.Expressions;
using System.Reflection;

namespace CloudPlatform.ORM.SQLSugar;

/// <summary>
/// ORM基础实现
/// </summary>
public partial class SQLSugarDefaultRepository : IRepositoryBase
{
    public SQLSugarDefaultRepository(ISqlSugarClient sqlSugarClient)
    {
        DynamicContext = Context = (SqlSugarClient)sqlSugarClient;
    }

    public SqlSugarClient Context { get; }

    public dynamic DynamicContext { get; }
}

/// <summary>
/// ORM基础实现
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public partial class SQLSugarDefaultRepository<TEntity> : IRepositoryBase<TEntity> where TEntity : class, new()
{
    private readonly IRepositoryBase _repositoryBase;

    /// <summary>
    /// 数据库上下文
    /// </summary>
    protected internal SqlSugarClient Context { get; }

    /// <summary>
    /// 数据库操作对象
    /// </summary>
    protected internal ISugarQueryable<TEntity> QueryableEntitie
    {
        get
        {
            if (TenantType == TenantStyle.TenantTable || IsSplitTable)
            {
                return Context.QueryableWithAttr<TEntity>().SplitTable();
            }
            else
            {
                return Context.QueryableWithAttr<TEntity>();
            }
        }
    }

    /// <summary>
    /// 租户类型
    /// </summary>
    protected internal TenantStyle TenantType { get; } = TenantStyle.None;

    /// <summary>
    /// ID类型
    /// </summary>
    private readonly GenerateIdStyle IdStyle = GenerateIdStyle.SnowflakeId;

    /// <summary>
    /// DynamicContext
    /// </summary>
    public dynamic DynamicContext { get; }

    /// <summary>
    /// 分表表名称标记
    /// </summary>
    protected internal string SplitTableTag = string.Empty;

    /// <summary>
    /// 是否开启分表
    /// </summary>
    protected internal bool IsSplitTable = false;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="repositoryBase"></param>
    public SQLSugarDefaultRepository(IRepositoryBase repositoryBase)
    {
        _repositoryBase = repositoryBase;

        DynamicContext = Context = (SqlSugarClient)repositoryBase.DynamicContext;

        var entityType = typeof(TEntity);

        IdStyle = entityType.GetProperty("Id")!.GetCustomAttribute<IdentityAttribute>(false)!.IdStyle;

        //定义租户特性,用于租户模式分表
        if (entityType.IsDefined(typeof(TenantTagAttribute), false))
        {
            var tenantTypeAttribute = entityType.GetCustomAttribute<TenantTagAttribute>(false)!;
            TenantType = tenantTypeAttribute.TenantType;
        }
        //当前对象是否定义了分表
        if (entityType.IsDefined(typeof(SplitTableAttribute), false))
        {
            IsSplitTable = true;
        }
        //SQLSugar 定义的租户特性目前用户切换数据库
        if (entityType.IsDefined(typeof(TenantAttribute), false))
        {
            var tenantAttribute = entityType.GetCustomAttribute<TenantAttribute>(false)!;
            Context.ChangeDatabase(tenantAttribute.configId);
        }
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            var table = entityType.GetCustomAttribute<SugarTable>(false)!;
            SplitTableTag = table.TableName;
        }
    }

    public Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression)
    {
        return QueryableEntitie.CountAsync(whereExpression);
    }

    public Task<bool> AnyAsync(Expression<Func<TEntity, bool>> whereExpression)
    {
        return QueryableEntitie.AnyAsync(whereExpression);
    }

    public Task<TEntity> SingleAsync(dynamic id)
    {
        return QueryableEntitie.InSingleAsync(id);
    }

    public List<TEntity> ToList()
    {
        return QueryableEntitie.ToList();
    }

    public Task<List<TEntity>> ToListAsync(Expression<Func<TEntity, bool>> whereExpression)
    {
        return QueryableEntitie.WhereIF(whereExpression != null, whereExpression).ToListAsync();
    }

    public Task<List<TEntity>> ToListAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression = null, OrderByStyle orderByType = OrderByStyle.Asc)
    {
        return QueryableEntitie.OrderByIF(orderByExpression != null, orderByExpression, (OrderByType)orderByType).WhereIF(whereExpression != null, whereExpression).ToListAsync();
    }

    public long InsertReturnId(TEntity entity)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.InsertableWithAttr(entity).SplitTable().ExecuteReturnSnowflakeId();
        }
        else
        {
            return Context.InsertableWithAttr(entity).ExecuteReturnSnowflakeId();
        }
    }

    public Task<long> InsertReturnIdAsync(TEntity entity)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.InsertableWithAttr(entity).SplitTable().ExecuteReturnSnowflakeIdAsync();
        }
        else
        {
            return Context.InsertableWithAttr(entity).ExecuteReturnSnowflakeIdAsync();
        }
    }

    public Task<int> InsertAsync(TEntity entity)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.InsertableWithAttr(entity).SplitTable().ExecuteCommandAsync();
        }
        else
        {
            return Context.InsertableWithAttr(entity).ExecuteCommandAsync();
        }
    }

    public Task<int> InsertAsync(IEnumerable<TEntity> entities)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.InsertableWithAttr(entities.ToList()).SplitTable().ExecuteCommandAsync();
        }
        else
        {
            return Context.InsertableWithAttr(entities.ToList()).ExecuteCommandAsync();
        }
    }

    public Task<int> UpdateAsync(TEntity entity)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.UpdateableWithAttr(entity).SplitTable(/*spt => spt.Where(tab => tab.TableName.Contains(SplitTableTag))*/).ExecuteCommandAsync();
        }
        else
        {
            return Context.UpdateableWithAttr(entity).ExecuteCommandAsync();
        }
    }

    public Task<int> UpdateAsync(IEnumerable<TEntity> entities)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.UpdateableWithAttr(entities.ToList()).SplitTable(/*spt => spt.Where(tab => tab.TableName.Contains(SplitTableTag))*/).ExecuteCommandAsync();
        }
        else
        {
            return Context.UpdateableWithAttr(entities.ToList()).ExecuteCommandAsync();
        }
    }

    public Task<int> DeleteAsync(TEntity entity)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.DeleteableWithAttr(entity).SplitTable(/*spt => spt.Where(tab => tab.TableName.Contains(SplitTableTag))*/).ExecuteCommandAsync();
        }
        else
        {
            return Context.DeleteableWithAttr(entity).ExecuteCommandAsync();
        }
    }

    public Task<int> DeleteAsync(object key)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.DeleteableWithAttr<TEntity>().In(key).SplitTable(/*spt => spt.Where(tab => tab.TableName.Contains(SplitTableTag))*/).ExecuteCommandAsync();
        }
        else
        {
            return Context.DeleteableWithAttr<TEntity>().In(key).ExecuteCommandAsync();
        }
    }

    public Task<int> DeleteAsync(object[] ids)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.DeleteableWithAttr<TEntity>().In(ids).SplitTable(spt => spt.Where(tab => tab.TableName.Contains(SplitTableTag))).ExecuteCommandAsync();
        }
        else
        {
            return Context.DeleteableWithAttr<TEntity>().In(ids).ExecuteCommandAsync();
        }
    }

    public Task<int> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression)
    {
        if (TenantType == TenantStyle.TenantTable || IsSplitTable)
        {
            return Context.DeleteableWithAttr<TEntity>().Where(whereExpression).SplitTable(/*spt => spt.Where(tab => tab.TableName.Contains(SplitTableTag))*/).ExecuteCommandAsync();
        }
        else
        {
            return Context.DeleteableWithAttr<TEntity>().Where(whereExpression).ExecuteCommandAsync();
        }
    }

    public IPage<TEntity> ToPageList(int pageIndex = 1, int pageSize = 10, Expression<Func<TEntity, bool>> whereExpression = null, Expression<Func<TEntity, object>> orderByExpression = null, OrderByStyle orderByType = OrderByStyle.Asc)
    {
        int totalCount = 0;

        var list = QueryableEntitie.WhereIF(whereExpression != null, whereExpression)
                    .OrderByIF(orderByExpression != null, orderByExpression, (OrderByType)orderByType)
                    .ToPageList(pageIndex, pageSize, ref totalCount);

        return new Page<TEntity>() { List = list, Total = totalCount, CurrentPage = pageIndex };
    }
}


异常日志

----------------------------------------------------------------------------------------------------
Date:2024-08-13 16:01:25.840
Version:1.0.0.0
UserName:
LogLevel:Error
Message:SQL执行报错:SELECT `secret`,`policy`,`action`,`ems_sn`,`ems_ver`,`cs_ver`,`id`,`device_name`,`sn`,`product_key`,`client_ip`,`status`,`iot_id`,`update_time`,`creation_time` FROM `device_status`   WHERE ( `sn` = '2407D00234' )   LIMIT 0,1
SqlSugar.SqlSugarException: This MySqlConnection is already in use. See https://fl.vu/mysql-conn-reuse

----------------------------------------------------------------------------------------------------

Date:2024-08-13 17:45:03.037
Version:1.0.0.0
UserName:admin
LogLevel:Error
Message:运行过程中过滤器捕获异常:缺少参数
CloudPlatform.Exceptions.AppException: 缺少参数
   at CloudPlatform.EnergyStorage.Application.Site.SiteAppService.GetDeviceListAsync(Int64[] ids) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.EnergyStorage.Application\Site\SiteAppService.cs:line 490
   at CloudPlatform.Aop.Transaction.TransactionAsyncInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.Aop\Transaction\TransactionAsyncInterceptor.cs:line 110
   at CloudPlatform.EnergyStorage.CustomerAPI.Station.SiteController.DeviceList(Int64[] ids) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.EnergyStorage.CustomerAPI\Station\SiteController.cs:line 93
   at lambda_method827(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

----------------------------------------------------------------------------------------------------
Date:2024-08-13 17:45:44.194
Version:1.0.0.0
UserName:admin
LogLevel:Error
Message:SQL执行报错:SELECT Count(*) FROM `tb_user`  WHERE ( 1 = 1 )   AND ( `tenant_id` = 572964436557893 )  AND ( `is_deleted` = 0 ) 
SqlSugar.SqlSugarException: This MySqlConnection is already in use. See https://fl.vu/mysql-conn-reuse

----------------------------------------------------------------------------------------------------
Date:2024-08-13 17:45:44.707
Version:1.0.0.0
UserName:admin
LogLevel:Error
Message:运行过程中过滤器捕获异常:This MySqlConnection is already in use. See https://fl.vu/mysql-conn-reuse
System.InvalidOperationException: This MySqlConnection is already in use. See https://fl.vu/mysql-conn-reuse
   at SqlSugar.MySqlProvider.GetScalarAsync(String sql, SugarParameter[] parameters)
   at SqlSugar.MySqlProvider.GetScalarAsync(String sql, SugarParameter[] parameters)
   at SqlSugar.QueryableProvider`1.GetCountAsync()
   at SqlSugar.QueryableProvider`1.CountAsync()
   at SqlSugar.QueryableProvider`1.ToPageListAsync(Int32 pageIndex, Int32 pageSize, RefAsync`1 totalNumber)
   at CloudPlatform.RbacService.UserService.ManyPageAsync(Int32 pageIndex, Int32 pageSize, Expression`1 whereExpression, Expression`1 orderByExpression) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.RbacService\UserService.cs:line 65
   at CloudPlatform.Aop.Transaction.TransactionAsyncInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.Aop\Transaction\TransactionAsyncInterceptor.cs:line 110
   at CloudPlatform.EnergyStorage.Application.Rbac.UserAppService.PageAsync(RequestPage`1 page) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.EnergyStorage.Application\Rbac\UserAppService.cs:line 116
   at CloudPlatform.Aop.Transaction.TransactionAsyncInterceptor.InternalInterceptAsynchronous[TResult](IInvocation invocation) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.Aop\Transaction\TransactionAsyncInterceptor.cs:line 110
   at CloudPlatform.EnergyStorage.ManagementAPI.RBAC.UserController.Page(RequestPage`1 page) in E:\Code\CloudPlatform\BackEnd\CloudPlatform\CloudPlatform.EnergyStorage.ManagementAPI\RBAC\UserController.cs:line 50
   at lambda_method864(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)


热忱回答6

  • 仓储中的 Context(SqlsugarClient) 对象期间有切换为单例对象的SqlSugarScope


    程序运行过程中有事件总线,处理器直接调用数据库仓储执行数据库操作


    目前我在想是不是 Context(SqlsugarClient)  对象过度使用导致的,

    0 回复
  • SqlSugarCore版本5.1.4.166

    0 回复
  • fate sta fate sta VIP0
    1个月前


    这个是线程安全问题,按你用的对象进行修改


    https://www.donet5.com/Home/Doc?typeId=1224

    0 回复
  • fate sta fate sta VIP0
    1个月前

    特别注意异步用法,还有仓储不要单例或者跨线程

    0 回复
  •    public class AsyncLocalSqlSugarContextAccessor
        {
            public static AsyncLocalDbContextAccessor Instance { get; } = new();
    
            public ISqlSugarClient? Current
            {
                get => _currentScope.Value;
                set => _currentScope.Value = value;
            }
    
            public AsyncLocalSqlSugarContextAccessor()
            {
                _currentScope = new AsyncLocal<ISqlSugarClient?>();
            }
    
            private readonly AsyncLocal<ISqlSugarClient> _currentScope;
        }

    老师我程序中添加一个数据库访问器,来获取数据库可以解决掉不

    0 回复
  • @fate sta:老师麻烦帮忙看看上面这个方案可以不

    0 回复