Pré-requisitos
- O .NET SDK 10. Este guia foi testado com o .NET SDK 10.0.401, o EF Core 10.0.12 e o
Npgsql.EntityFrameworkCore.PostgreSQL10.0.3 (Npgsql 10.0.3). - Uma conta no ClickHouse Cloud
psql, para criar o banco de dados. Você também pode executar a instruçãoCREATE DATABASEno SQL Console.
Crie um serviço ClickHouse Managed Postgres
No console do ClickHouse Cloud, clique em New service e selecione Postgres. A instância fica pronta em poucos minutos. Consulte o guia de início rápido para um passo a passo completo.Obtenha os detalhes de conexão
Clique em Connect na barra lateral esquerda do seu serviço. Mantenha Directly selecionado, ative Use SSL e copie a senha e o hostname do servidor. Em seguida, clique em Download CA certificate. Você também pode baixar o certificado mais tarde em Settings → CA Certificate. Ele é exclusivo da sua instância, o que permite ao Npgsql verificar se está de fato se comunicando com o seu servidor. Este guia se conecta diretamente ao Postgres na porta5432, tanto para a aplicação quanto para as migrations do EF Core. Uma aplicação ASP.NET Core é um processo de longa duração, e o Npgsql já mantém um pool de conexões dentro dela (até 100 por string de conexão, por padrão), portanto não é necessário um segundo pooler. Se você executar muitas instâncias da aplicação, consulte Use o PgBouncer.
O modal Connect não tem uma aba .NET, e o Npgsql não aceita a URL postgresql:// da aba url. Em vez disso, ele usa strings de conexão no formato Keyword=Value. Pegue os valores da URL e mapeie-os para as palavras-chave do Npgsql:
Configure o projeto
Crie um projeto ASP.NET Core, adicione o provedor Npgsql para EF Core e o pacote de design-time do EF Core e, em seguida, instale a ferramenta de linha de comandodotnet ef:
Configure a conexão
Mova o certificado da CA que você baixou para o diretório do projeto e renomeie-o paraca-certificate.pem.
Crie um banco de dados para a aplicação. Substitua <PASSWORD> e o host pelos valores exibidos no modal Connect:
appsettings.json e do controle de versão:
Development, que é o ambiente usado por padrão por dotnet run e dotnet ef. Em produção, defina a variável de ambiente ConnectionStrings__TodoDb.
Com SSL Mode=VerifyFull, o Npgsql verifica se o certificado do servidor foi assinado pela CA indicada em Root Certificate e se ele corresponde ao hostname. O Npgsql resolve um caminho relativo em Root Certificate a partir do diretório de trabalho atual, que é o diretório do projeto quando você usa dotnet run e dotnet ef. Se você iniciar a aplicação a partir de outro local, use um caminho absoluto.
Se a CA estiver incorreta ou ausente, ou se o host não corresponder ao certificado (por exemplo, ao conectar por endereço IP), a conexão falha com
Exception while performing SSL handshake e o erro interno The remote certificate was rejected by the provided RemoteCertificateValidationCallback. Se o arquivo de Root Certificate não existir, o erro interno é Could not find file. Observe também que:- O padrão do Npgsql é
SSL Mode=Prefer, eSSL Mode=Requiretambém não verifica o certificado, mesmo quando você defineRoot Certificate. Sempre definaSSL Mode=VerifyFull. - O Npgsql lê as variáveis de ambiente
PGSSLROOTCERTePGPASSWORD, mas nãoPGHOSTnemPGSSLMODE. Por isso, as variáveis da aba env do modal Connect não bastam por si só.
Defina o modelo
Crie o arquivoTodo.cs com a classe de entidade:
Todo.cs
TodoDb.cs com o DbContext:
TodoDb.cs
Program.cs. Ele registra o TodoDb com o provedor Npgsql e mapeia um endpoint para cada operação. Em uma aplicação existente, basta a chamada AddDbContext com UseNpgsql:
Program.cs
/db/tls consulta pg_stat_ssl para a própria sessão de banco de dados da aplicação, o que permite verificar se a conexão está criptografada.
Crie o schema
Gere uma migração a partir do model e aplique-a:dotnet ef migrations add grava a migração na pasta Migrations, e dotnet ef database update a aplica e a registra na tabela __EFMigrationsHistory. Na primeira execução, o EF Core registra no log um SELECT com falha em __EFMigrationsHistory antes de criar a tabela; você pode ignorá-lo.
Antes de aplicar as migrations, o EF Core adquire um bloqueio para impedir que duas implantações migrem o mesmo banco de dados ao mesmo tempo. Com o Npgsql, o bloqueio é um LOCK TABLE em __EFMigrationsHistory dentro da transação de migração, e não um advisory lock no nível da sessão; por isso, ele é liberado quando a transação termina.
Executar e verificar
Inicie a aplicação na porta3115:
DELETE retorna 204 No Content, por isso sua linha fica vazia.
Verifique se a sessão de banco de dados do app usa TLS:
guide_dotnet e, em seguida, public e clique na tabela Todos. O EF Core usa os nomes de classes e propriedades como identificadores entre aspas; por isso, a tabela se chama "Todos" e as colunas são "Id", "Title" e assim por diante. A tabela contém a linha restante:
Use o PgBouncer
O Npgsql abre até 100 conexões por instância da aplicação (Maximum Pool Size). Se várias instâncias, somadas, se aproximarem do limite de conexões do Postgres, conecte a aplicação pelo PgBouncer incluído. Selecione via PgBouncer no modal Connect e altere a porta na string de conexão para 6432:
- Prepared statements: o EF Core não prepara instruções, e a preparação automática do Npgsql vem desativada por padrão (
Max Auto Prepare=0), então as consultas usam instruções sem nome, que funcionam através do PgBouncer. Mantenha essa configuração. Através do PgBouncer, prepared statements criados comMax Auto PrepareouNpgsqlCommand.Preparefalham de forma intermitente com08P01: prepared statement did not exist(No Reset On Close=trueevita isso) e, depois que uma migration altera o tipo de uma coluna, continuam falhando comcached plan must not change result type, mesmo em novas conexões. Se você precisar de prepared statements, conecte-se diretamente. - Estado da sessão: configurações definidas com
SET, incluindosearch_path, não persistem entre transações. Em vez disso, useSET LOCALdentro de uma transação. O PgBouncer rejeita as palavras-chave de string de conexãoSearch PatheOptionscomunsupported startup parameter; jáTimezoneeApplication Namefuncionam. - Migrations:
dotnet ef database updatetambém funciona através do PgBouncer, porque o bloqueio da migration é um bloqueio de tabela que se encerra junto com a respectiva transação. - Verificação de TLS:
pg_stat_ssldescreve a conexão entre o PgBouncer e o Postgres, então/db/tlsretornanone. A conexão da sua aplicação com o PgBouncer continua sendo verificada: um certificado CA incorreto gera a mesma falha.
Próximos passos
- Conexão: strings de conexão, PgBouncer e TLS
- Configurações: parâmetros do Postgres e do PgBouncer, como
max_connections - Réplicas de leitura: envie consultas read-only para uma réplica
- Segurança: listas de acesso por IP e rede privada