dbcontext 上下文池,提高性能测试
continuous-integration/drone/push Build is passing Details

IRC_NewDev
hang 2024-08-02 17:03:23 +08:00
parent e1038c27f6
commit c353ae645b
5 changed files with 75 additions and 30 deletions

View File

@ -45,8 +45,8 @@ namespace IRaCIS.Core.SCP
.PropertiesAutowired().AsImplementedInterfaces();
containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
//containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
//containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();

View File

@ -1,4 +1,6 @@
using IRaCIS.Core.Infra.EFCore;
using EntityFramework.Exceptions.SqlServer;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using Medallion.Threading;
using Medallion.Threading.SqlServer;
using Microsoft.EntityFrameworkCore;
@ -11,15 +13,25 @@ namespace IRaCIS.Core.SCP
{
public static void AddEFSetup( this IServiceCollection services, IConfiguration configuration)
{
//services.AddScoped<DbContext, IRaCISDBContext>();
services.AddHttpContextAccessor();
services.AddScoped<IUserInfo, UserInfo>();
//这个注入没有成功--注入是没问题的构造函数也只是支持参数就好错在注入的地方不能写DbContext
//Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量 这在概念上类似于ADO.NET Provider原生的连接池操作方式具有节省DbContext实例化成本的优点
services.AddDbContext<IRaCISDBContext>(options =>
services.AddPooledDbContextFactory<IRaCISDBContext>(options =>
{
// 在控制台
//public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); });
var logFactory = LoggerFactory.Create(builder => { builder.AddDebug(); });
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value,
contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
options.UseLoggerFactory(logFactory);
options.UseExceptionProcessor();
options.EnableSensitiveDataLogging();
options.AddInterceptors(new QueryWithNoLockDbCommandInterceptor());
@ -30,6 +42,12 @@ namespace IRaCIS.Core.SCP
});
// Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above,
services.AddScoped<IRaCISDBScopedFactory>();
// Finally, arrange for a context to get injected from our Scoped factory:
services.AddScoped(sp => sp.GetRequiredService<IRaCISDBScopedFactory>().CreateDbContext());
//注意区分 easy caching 也有 IDistributedLockProvider
services.AddSingleton<IDistributedLockProvider>(sp =>
{
@ -38,7 +56,6 @@ namespace IRaCIS.Core.SCP
return new SqlDistributedSynchronizationProvider(configuration.GetSection("ConnectionStrings:RemoteNew").Value);
});
//services.AddAssemblyTriggers(typeof(SubjectVisitImageDateTrigger).Assembly);
}
}
}

View File

@ -55,8 +55,8 @@ namespace IRaCIS.Core.API
containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
//containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
//containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();
//注册hangfire任务 依赖注入

View File

@ -1,11 +1,15 @@
using Hangfire.SqlServer;
using Castle.Core.Logging;
using EntityFramework.Exceptions.SqlServer;
using Hangfire.SqlServer;
using IRaCIS.Core.Application.Triggers;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using Medallion.Threading;
using Medallion.Threading.SqlServer;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
namespace IRaCIS.Core.API
@ -14,15 +18,28 @@ namespace IRaCIS.Core.API
{
public static void AddEFSetup( this IServiceCollection services, IConfiguration configuration)
{
//services.AddScoped<DbContext, IRaCISDBContext>();
services.AddHttpContextAccessor();
services.AddScoped<IUserInfo, UserInfo>();
// First, register a pooling context factory as a Singleton service, as usual:
//这个注入没有成功--注入是没问题的构造函数也只是支持参数就好错在注入的地方不能写DbContext
//Web程序中通过重用池中DbContext实例可提高高并发场景下的吞吐量 这在概念上类似于ADO.NET Provider原生的连接池操作方式具有节省DbContext实例化成本的优点
services.AddDbContext<IRaCISDBContext>(options =>
services.AddPooledDbContextFactory<IRaCISDBContext>(options =>
{
// 在控制台
//public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); });
var logFactory = LoggerFactory.Create(builder => { builder.AddDebug(); });
options.UseSqlServer(configuration.GetSection("ConnectionStrings:RemoteNew").Value,
contextOptionsBuilder => contextOptionsBuilder.EnableRetryOnFailure());
options.UseLoggerFactory(logFactory);
options.UseExceptionProcessor();
options.EnableSensitiveDataLogging();
options.AddInterceptors(new QueryWithNoLockDbCommandInterceptor());
@ -62,6 +79,12 @@ namespace IRaCIS.Core.API
});
// Register an additional context factory as a Scoped service, which gets a pooled context from the Singleton factory we registered above,
services.AddScoped<IRaCISDBScopedFactory>();
// Finally, arrange for a context to get injected from our Scoped factory:
services.AddScoped(sp => sp.GetRequiredService<IRaCISDBScopedFactory>().CreateDbContext());
//注意区分 easy caching 也有 IDistributedLockProvider
services.AddSingleton<IDistributedLockProvider>(sp =>
{

View File

@ -24,33 +24,38 @@ using IRaCIS.Core.Infrastructure;
namespace IRaCIS.Core.Infra.EFCore
{
public class IRaCISDBScopedFactory : IDbContextFactory<IRaCISDBContext>
{
private readonly IDbContextFactory<IRaCISDBContext> _pooledFactory;
private readonly IUserInfo _userInfo;
public IRaCISDBScopedFactory(IDbContextFactory<IRaCISDBContext> pooledFactory,IUserInfo userInfo)
{
_pooledFactory = pooledFactory;
_userInfo = userInfo;
}
public IRaCISDBContext CreateDbContext()
{
var context = _pooledFactory.CreateDbContext();
context._userInfo = _userInfo;
return context;
}
}
public class IRaCISDBContext : DbContext
{
public readonly IUserInfo _userInfo;
public IUserInfo _userInfo;
public readonly ILogger<IRaCISDBContext> _logger;
// 在控制台
//public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); });
// 调试窗口
public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddDebug(); });
public IRaCISDBContext(DbContextOptions<IRaCISDBContext> options, IUserInfo userInfo, ILogger<IRaCISDBContext> logger
public IRaCISDBContext(DbContextOptions<IRaCISDBContext> options, ILogger<IRaCISDBContext> logger
) : base(options)
{
_logger= logger;
_userInfo = userInfo;
}
//比数据库上下文构造函数先执行 不能构造函数注入的方式使用配置文件
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseLoggerFactory(MyLoggerFactory);
optionsBuilder.UseExceptionProcessor();
}