.net core 2.1.5和实体框架已达到最大池大小

.net core 2.1.5和实体框架已达到最大池大小,.net,performance,entity-framework,.net-core,.net,Performance,Entity Framework,.net Core,我正在开发一个.NETCore应用程序,其中该应用程序正在最大化池大小,.NETCore的版本是2.1.5,EF也是版本2。最大池大小为1500 “超时已过期。在获取超时之前已过超时时间。” 来自池的连接。发生这种情况的原因可能是所有池都已连接 连接正在使用,已达到最大池大小。“ 这个特定的API有很多只读查询,所以QueryTracking被设置为noTracking被禁用,下面是DBContext代码 namespace Microsoft.Extensions.DependencyInje

我正在开发一个.NETCore应用程序,其中该应用程序正在最大化池大小,.NETCore的版本是2.1.5,EF也是版本2。最大池大小为1500

“超时已过期。在获取超时之前已过超时时间。” 来自池的连接。发生这种情况的原因可能是所有池都已连接 连接正在使用,已达到最大池大小。“

这个特定的API有很多只读查询,所以QueryTracking被设置为noTracking被禁用,下面是DBContext代码

namespace Microsoft.Extensions.DependencyInjection
{
    public static class Wireup
    {
        public static void WireUpClients(this IServiceCollection services, string ClientsDbConnectionString)
        {
            WireupCommon(services);

            services.WireUpCommonMutators();

            var config = new MapperConfiguration(cfg => { cfg.AddProfile<ClientsMappingProfile>(); });
            var mapper = config.CreateMapper();
            services.TryAddSingleton(new ClientsMapper(mapper));

            services.AddDbContext<ReplacementFieldsDbContext>(
                options => options.UseSqlServer(ClientsDbConnectionString));

            services.AddDbContext<ClientsDbContext>(options => options.UseSqlServer(ClientsDbConnectionString));
            services.AddDbContext<NomenclaturesDbContext>(
                options => options.UseSqlServer(ClientsDbConnectionString));

            services.AddDbContext<ClientsCombinedDbContext>(
                options => options.UseSqlServer(ClientsDbConnectionString));

       ........
            services.TryAddTransient<IClientsImpactingReleasesHelper, ClientsImpactingReleasesHelper>();
        }

        public static void WireupCommon(IServiceCollection services)
        {
            services.WireUpCommonUtil(); // Should go first to inject IAmbientRelease
            services.WireUpCommonCore();
            services.WireUpCommonRepo();
            services.WireUpCommonServices();
            services.WireUpCommonComponents();
        }
    }
}
正在为Clients.Repositories.ClientsDbContext引发该错误-

An exception occurred in the database while iterating the results of a query for context type 'Clients.Repositories.ClientsDbContext'.
System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.
   at System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
首先启用

使用正确的方法实现ServiceCollection扩展模式,如下所示

using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services; // very important
        }
    }
}
使用ConfigSample.Options;
使用Microsoft.Extensions.Configuration;
命名空间Microsoft.Extensions.DependencyInjection
{
公共静态类MyConfigServiceCollectionExtensions
{
公共静态IServiceCollection AddConfig(
此IServiceCollection服务,IConfiguration配置)
{
服务。配置(
config.GetSection(PositionOptions.Position));
服务。配置(
config.GetSection(ColorOptions.Color));
返回服务;//非常重要
}
}
}


我建议您将该项目更新到.NET 5,没有bug。应用程序正在泄漏连接和上下文。这些DbContext实例在何处以及如何使用?他们有过这样的想法吗?您正在构建什么样的应用程序?在web应用程序中,每个HTTP请求都是一个单独的上下文,因此当处理请求的操作退出时,通过构造函数注入注入控制器的每个DbContext实例总是由ASP.NET核心中间件处理。要耗尽池,您的应用程序正在执行其他操作。我猜您没有在控制器中使用DbContext,或者甚至没有web应用程序。我怀疑您每次都在没有作用域的情况下创建一个新的DbContext实例,并且从不处理它,从而使许多DbContext实例处于活动状态。此外,我怀疑您将事务保持打开状态,否则DbContext将无法保持任何连接打开。DbContext仅在读取数据、使用
SaveChanges
保存数据或代码使用显式数据库事务时打开事务感谢您的初始外观让我添加更多详细信息@panagiotiskanavos将代码显示为文本,而不是图像。无法复制、编译、测试或删除图像googled@PanagiotisKanavos请查看更新的详细信息-让我知道是否需要其他帮助谢谢您的回复-我尝试添加它得到一些错误-让我找到其他需要修改的内容将更新“无法池,因为它没有接受DbContextOptions类型的单个参数的单个公共构造函数。”
namespace Clients.Repositories
{
    public class ClientsRepository<TEntity> : BaseRepository<ClientsDbContext>, IClientsRepository<TEntity>
        where TEntity : BaseClient, new()
    {

        private readonly bool _isBestPracticeRepo = typeof(TEntity) == typeof(BestPractice);
        private readonly IItemVersionValidator _itemVersionValidator;
        private readonly IApprovalHelper _approvalHelper;

        public ClientsRepository(ClientsDbContext context, IAmbientRelease ambientRelease,
            IItemVersionValidator itemVersionValidator, IApprovalHelper approvalHelper) : base(context)
        {
            _ambientRelease = ambientRelease;
            _itemVersionValidator = itemVersionValidator;
            _approvalHelper = approvalHelper;
        }

        //filter to BP or Client rows only 
        public IQueryable<ClientVersion> FilteredClientVersions => FilteredVersions();

        
        public IQueryable<ClientVersion> ClientVersions => _context.ClientVersions.Include(c => c.Client);

        public IQueryable<ClientVersion> CurrentClientVersions => FilteredCurrentVersions();

        public IQueryable<ClientVersion> ApprovedCurrentClientVersions => FilteredApprovedCurrentVersions();

        public async Task<ClientVersion> GetClientVersionWithRelatedData(Guid releaseKey, CancellationToken cancellationToken)
            => await _context.ClientVersions.Include(o => o.Client).Include(o => o.BestPractice)
            .Where(o => o.ReleaseKey == releaseKey).SingleOrDefaultAsync(cancellationToken);

        public IQueryable<NamedEntityOverTime> ClientNamesOverTime =>
            _context.ClientNamesOverTime.FromSql("SELECT * FROM [ClientNamesOverTime]");

        public async Task<ClientVersion> Create(ClientVersion clientVersion, CancellationToken cancellationToken)
        {
             
            clientVersion.ClientId = clientVersion.Client?.ClientId ?? clientVersion.ClientId;
            clientVersion.Client = clientVersion.ClientId == 0 ? new TEntity() : null;

            await ValidateClientVersionCreate(clientVersion, cancellationToken);

            var entry = await _context.ClientVersions.AddAsync(clientVersion, cancellationToken);
            await _context.SaveChangesAsync(cancellationToken);
            return entry.Entity;
        }

        public async Task<ClientVersion> Update(ClientVersion clientVersion, CancellationToken cancellationToken)
        {
            var entry = _context.ClientVersions.Update(clientVersion);
            await _context.SaveChangesAsync(cancellationToken);

            return entry.Entity;
        }
 
        

        public async Task<bool> IsBestPractice(long clientId, CancellationToken cancellationToken)
        {
            return (await _context.BaseClients.FirstAsync(bc => bc.ClientId == clientId)) is BestPractice;
        }

        private IQueryable<ClientVersion> FilteredCurrentVersions()
        {
            return _context.ClientVersions.Include(e => e.Client).FromSql("SELECT * FROM [CurrentClientVersion]")
                .Where(v => EF.Property<bool>(v.Client, "IsBestPractice") == _isBestPracticeRepo).AsQueryable();
        }

        private IQueryable<ClientVersion> FilteredApprovedCurrentVersions()
        {
            return _context.ClientVersions.Include(e => e.Client).FromSql("SELECT * FROM [ApprovedCurrentClientVersion]")
                .Where(v => EF.Property<bool>(v.Client, "IsBestPractice") == _isBestPracticeRepo).AsQueryable();
        }

        private IQueryable<ClientVersion> FilteredVersions()
        {
            return _context.ClientVersions
                .Where(v => EF.Property<bool>(v.Client, "IsBestPractice") == _isBestPracticeRepo).AsQueryable();
        }

        public async Task ValidateClientVersionCreate(ClientVersion version, CancellationToken cancellationToken)
        {
            var versionQuery = _context.ClientVersions.Where(v => v.ClientId == version.ClientId);
            await _itemVersionValidator.ValidateUniqueReleaseDate(versionQuery, "Client", version.Name, cancellationToken);
        }

    }
}
_context.BaseClients.FromSql(sql, releaseKeyParam, asOfParam, clientIdParam)
                .Select(c => c.ClientId).ToListAsync(cancellationToken);
An exception occurred in the database while iterating the results of a query for context type 'Clients.Repositories.ClientsDbContext'.
System.InvalidOperationException: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.
   at System.Data.Common.ADP.ExceptionWithStackTrace(Exception e)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
using ConfigSample.Options;
using Microsoft.Extensions.Configuration;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class MyConfigServiceCollectionExtensions
    {
        public static IServiceCollection AddConfig(
             this IServiceCollection services, IConfiguration config)
        {
            services.Configure<PositionOptions>(
                config.GetSection(PositionOptions.Position));
            services.Configure<ColorOptions>(
                config.GetSection(ColorOptions.Color));

            return services; // very important
        }
    }
}