Используйте несколько экземпляров DbContext при использовании AddDbContextPool - PullRequest
0 голосов
/ 13 января 2020

Я использую реализацию GraphQL на моем ASP. NET Core 3.1 веб-сервере. Он выполняет несколько методов распознавателя, которым требуется DbContext через внедрение зависимостей в одном запросе. Раньше я настраивал AddDbContext с contextLifetime, установленным на ServiceLifetime.Transient, чтобы избежать параллельных операций с одним и тем же DbContext. Теперь я хотел бы переключиться на AddDbContextPool, чтобы повторно использовать экземпляры DbContext между запросами, а также в том же запросе . Есть ли способ как-то этого добиться?

1 Ответ

0 голосов
/ 03 февраля 2020

В исходной реализации по умолчанию AddDbContextPool использует AddScoped

public static IServiceCollection AddDbContextPool<TContextService, TContextImplementation>(
      [NotNull] this IServiceCollection serviceCollection,
      [NotNull] Action<IServiceProvider, DbContextOptionsBuilder> optionsAction,
      int poolSize = 128)
      where TContextService : class
      where TContextImplementation : DbContext, TContextService
    {
      Check.NotNull<IServiceCollection>(serviceCollection, nameof (serviceCollection));
      Check.NotNull<Action<IServiceProvider, DbContextOptionsBuilder>>(optionsAction, nameof (optionsAction));
      if (poolSize <= 0)
        throw new ArgumentOutOfRangeException(nameof (poolSize), CoreStrings.InvalidPoolSize);
      EntityFrameworkServiceCollectionExtensions.CheckContextConstructors<TContextImplementation>();
      EntityFrameworkServiceCollectionExtensions.AddCoreServices<TContextImplementation>(serviceCollection, (Action<IServiceProvider, DbContextOptionsBuilder>) ((sp, ob) =>
      {
        optionsAction(sp, ob);
        CoreOptionsExtension extension = (ob.Options.FindExtension<CoreOptionsExtension>() ?? new CoreOptionsExtension()).WithMaxPoolSize(new int?(poolSize));
        ((IDbContextOptionsBuilderInfrastructure) ob).AddOrUpdateExtension<CoreOptionsExtension>(extension);
      }), ServiceLifetime.Singleton);
      serviceCollection.TryAddSingleton<DbContextPool<TContextImplementation>>((Func<IServiceProvider, DbContextPool<TContextImplementation>>) (sp => new DbContextPool<TContextImplementation>((DbContextOptions) sp.GetService<DbContextOptions<TContextImplementation>>())));

      //SEE THIS LINE HERE
      serviceCollection.AddScoped<DbContextPool<TContextImplementation>.Lease>();


      serviceCollection.AddScoped<TContextService>((Func<IServiceProvider, TContextService>) (sp => (TContextService) sp.GetService<DbContextPool<TContextImplementation>.Lease>().Context));
      return serviceCollection;
    }

Добавление AddDbContextPool на ConfigureServices должно быть достаточно

services.AddDbContextPool<YardCheckDBContext>(options => options.UseSqlServer(connection));

Кроме того, это помогает вам улучшить средний запрос в секунду, для получения дополнительной ссылки см. эту статью, где вы можете найти сравнение с DbContextPool или без. Надеюсь, это поможет

DbContext Pool

...