#asp.net-core #.net-core #entity-framework-core #snowflake-cloud-data-platform #hotchocolate
Вопрос:
У меня есть пользовательский DbContext SnowflakeDbContext, который мне нужно инициализировать с помощью SnowflakeDbConnection, чтобы он работал:
public class SnowflakeDbContext : DbContext
{
private readonly string connectionString = "";
public SnowflakeDbContext(DbContextOptions<SnowflakeDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
var dbConnection = new SnowflakeDbConnection()
{
ConnectionString = this.connectionString
};
optionsBuilder.UseSqlServer(dbConnection);
optionsBuilder.AddInterceptors(new SnowflakeCommandInterceptor());
}
public DbSet<Opportunity> Opportunities { get; set; } = default!;
public DbSet<Account> Accounts { get; set; } = default!;
}
Это хорошо работает с EF Core 5, были в Startup.cs (я использую ASP.NET Веб-приложение Core 5) Я использую
.AddDbContext<SnowflakeDbContext>(ServiceLifetime.Singleton)
Я хочу использовать SnowflakeDbContext с HotChocolate, где рекомендуется использовать AddPooledDbContextFactory<><> для поддержки объединения соединений и предоставления системе возможности совершать одновременные вызовы (описано здесь).
Я изменил файл Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services
.AddPooledDbContextFactory<SnowflakeDbContext>(options =>
{
var dbConnection = new SnowflakeDbConnection()
{
ConnectionString = this.connectionString
};
options.UseSqlServer(dbConnection);
options.AddInterceptors(new SnowflakeCommandInterceptor());
})
.AddGraphQLServer()
.AddQueryType<Query>();
}
Используя следующий запрос GraphQL (который использует параллельные запросы):
query GetAccountsInParallel {
a: accounts {
id, name
}
b: accounts {
id, name
}
c: accounts {
id, name
}
}
Я получаю следующую ошибку:
"No service for type 'SnowflakeGraphQL.Snowflake.SnowflakeDbContext' has been registered.",
Я могу добавить
.AddDbContext<SnowflakeDbContext>()
в Startup.cs после вызова .AddPooledDbContextFactory<>. Теперь я получаю другую ошибку:
"A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext."
Все примеры, которые я видел в Интернете, используют .UseSqlServer(строка подключения), где мне нужно использовать версию .UseSqlServer(DbConnection), чтобы иметь доступ к нашей базе данных Snowflake.
Как настроить мое приложение в Startup.cs для использования .AddPooledDbContextFactory()?
Обновление: Начиная с кода graphql-workshop и заменяя Sqlite сначала на SQLServer, а затем на SQLServer, используя мой SnowflakeDbContext, я заставляю его работать, поэтому где-то в моем коде должна быть небольшая разница, как описано выше, которая приводит к сбою в моем случае.
Комментарии:
1. Используете ли вы более одного DbContext?
2. @u1986237 нет, я использую только SnowflakeDbContext, но мой запрос GraphQL GetAccountsInParallel вызывает 3 запроса параллельно (один и тот же код запроса для всех 3).
Ответ №1:
При извлечении записей учетных записей нам нужно использовать [ScopedService], а не [Службу], как это:
[UseApplicationDbContext]
public async Task<List<Account>> GetAccounts([ScopedService] SnowflakeDbContext context) => await context.Accounts.ToListAsync();