Postgres Npgsql 连接池与代码

问题描述 投票:0回答:1

我知道这篇文章:Postgres Npgsql 连接池 但这并没有完全解决我的问题。

我从概念上理解连接池是如何工作的,但我很难理解如何使用 Npgsql 将它们应用到我的 .NET 应用程序中。

这是我目前正在做的事情:

NpgsqlConnectionStringBuilder cb ...    // build command and set properties
cb.Pool = True                         // set pool setting to True and set max pool

NpgsqlConnection conn =  new NpgsqlConnection(cb.ConnectionString)

public void thread1()
    NpgsqlCommand cmd = new NpgsqlCommand(conn)
    cmd.Connection.Open()
    // code
    cmd.ExecuteNonQuery
    
    cmd.Connection.Close()

public void thread2() {
    //... same thing
}

据我所知,每当我发出新命令时,我实际上只是从连接池中获取相同的连接。我不明白如何通过仅创建一个 NpgsqlConnection 对象来利用连接池的其余部分。

当我执行 NpgsqlConnection.Open() (又名 conn.Open()) 与 cmd.Connection.Open() 时会发生什么?

我觉得有一些基本的东西我不明白。

c# postgresql connection-pooling npgsql pool
1个回答
0
投票

对于 ASP.NET,这是我的实现..

初始化

  • 连接构建器助手
public static class ConnectionHelper
{
    public static NpgsqlDataSource CreateDataSource(string connectionString, Action<NpgsqlDataSourceBuilder>? customConfigurationSetter = null)
    {
        var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString);

        customConfigurationSetter?.Invoke(dataSourceBuilder);

        var dataSource = dataSourceBuilder.Build();

        return dataSource;
    }
}
  • 将NpgsqlDataSource注册为Singleton,这一点至关重要,每个实例都有自己的连接池
builder.Services.AddSingleton<NpgsqlDataSource, NpgsqlDataSource>(provider =>
{
    var connectionString = configuration.GetConnectionString("Database");

    return ConnectionHelper.CreateDataSource(connectionString);
})
  • DatabaseProvider
    中,或者无论你如何称呼你调用数据库的地方,使用依赖注入来为你提供
    NpgsqlDataSource
  • 的实例
private readonly ILogger<DatabaseProvider> logger;
private readonly NpgsqlDataSource dataSource;

public DatabaseProvider(ILogger<DatabaseProvider> logger, NpgsqlDataSource dataSource)
{
    this.logger = logger;
    this.dataSource = dataSource;
}

与 DBCommand 一起使用

  • 当您创建 SqlCommand 时,使用像这样的
    NpgsqlDataSource.CreateCommand
    方法,并将其与 wait 一起使用
await using command = dataSource.CreateCommand("select * from table1");

await using var reader = await command.ExecuteReaderAsync(cancellationToken);
while (await reader.ReadAsync(cancellationToken))
{
  // ...
}

注意:

无需打开连接。 DBCommand 自动执行此操作。

© www.soinside.com 2019 - 2024. All rights reserved.