Requisitos previos
- El SDK de .NET 10. Esta guía se probó con el SDK de .NET 10.0.401, EF Core 10.0.12 y
Npgsql.EntityFrameworkCore.PostgreSQL10.0.3 (Npgsql 10.0.3). - Una cuenta de ClickHouse Cloud
psql, para crear la base de datos. También puede ejecutar la sentenciaCREATE DATABASEen la consola SQL.
Crear un servicio de ClickHouse Managed Postgres
En la consola de ClickHouse Cloud, haga clic en New service y seleccione Postgres. La instancia estará lista en pocos minutos. Consulte la guía de inicio rápido para ver las instrucciones paso a paso.Obtén los detalles de conexión
Haz clic en Conectar en la barra lateral izquierda de tu servicio. Mantén seleccionada la opción Directly, activa Use SSL y copia la contraseña y el nombre del host del servidor. A continuación, haz clic en Download CA certificate. También puedes descargar el certificado más adelante desde Settings → CA Certificate. Es exclusivo de tu instancia, así que Npgsql puede usarlo para verificar que se está comunicando con tu servidor. Esta guía se conecta directamente a Postgres en el puerto5432, tanto desde la aplicación como para las migraciones de EF Core. Una aplicación ASP.NET Core es un proceso de larga duración en el que Npgsql ya gestiona un pool de conexiones (hasta 100 por cadena de conexión de forma predeterminada), por lo que no hace falta un segundo pooler. Si ejecutas muchas instancias de la aplicación, consulta Usar PgBouncer.
El modal Conectar no tiene una pestaña para .NET, y Npgsql no acepta la URL postgresql:// de la pestaña url, sino que utiliza cadenas de conexión con el formato Keyword=Value. Toma los valores de la URL y asígnalos a las palabras clave de Npgsql:
Configurar el proyecto
Cree un proyecto ASP.NET Core, agregue el provider de EF Core para Npgsql y el paquete de tiempo de diseño de EF Core, e instale la herramienta de línea de comandosdotnet ef:
Configurar la conexión
Mueva el certificado de CA que descargó al directorio del proyecto y cámbiele el nombre aca-certificate.pem.
Cree una base de datos para la aplicación. Sustituya <PASSWORD> y el host por los valores que aparecen en el modal Conectar:
appsettings.json y del control de versiones:
Development, que es el que usan de forma predeterminada dotnet run y dotnet ef. En producción, configure en su lugar la variable de entorno ConnectionStrings__TodoDb.
SSL Mode=VerifyFull hace que Npgsql compruebe que el certificado del servidor esté firmado por la CA indicada en Root Certificate y que coincida con el nombre del host. Npgsql resuelve una ruta relativa de Root Certificate con respecto al directorio de trabajo actual, que es el directorio del proyecto cuando se usan dotnet run y dotnet ef. Use una ruta absoluta si inicia la aplicación desde otra ubicación.
Si la CA es incorrecta o no existe, o si el host no coincide con el certificado (por ejemplo, al conectarse mediante una dirección IP), la conexión falla con
Exception while performing SSL handshake y el error interno The remote certificate was rejected by the provided RemoteCertificateValidationCallback. Si el archivo de Root Certificate no existe, el error interno es Could not find file. Tenga en cuenta, además, que:- El valor predeterminado de Npgsql es
SSL Mode=Prefer, ySSL Mode=Requiretampoco verifica el certificado, aunque se configureRoot Certificate. Configure siempreSSL Mode=VerifyFull. - Npgsql lee las variables de entorno
PGSSLROOTCERTyPGPASSWORD, pero noPGHOSTniPGSSLMODE. Por lo tanto, las variables de la pestaña env del modal Conectar no bastan por sí solas.
Definir el modelo
CreeTodo.cs con la clase de entidad:
Todo.cs
TodoDb.cs con el DbContext:
TodoDb.cs
Program.cs. Este código registra TodoDb con el provider de Npgsql y asigna un endpoint a cada operación. En una aplicación existente, solo necesita la llamada a AddDbContext con UseNpgsql:
Program.cs
/db/tls lee pg_stat_ssl para la sesión de base de datos de la propia aplicación, lo que le permite comprobar que la conexión está cifrada.
Crear el esquema
Genere una migración a partir del modelo y aplíquela:dotnet ef migrations add escribe la migración en la carpeta Migrations, y dotnet ef database update la aplica y la registra en la tabla __EFMigrationsHistory. En la primera ejecución, EF Core registra en el log un SELECT fallido sobre __EFMigrationsHistory antes de crear la tabla; puede ignorarlo.
Antes de aplicar las migraciones, EF Core adquiere un bloqueo para que dos implementaciones no puedan migrar la misma base de datos simultáneamente. Con Npgsql, el bloqueo es un LOCK TABLE sobre __EFMigrationsHistory dentro de la transacción de migración, no un bloqueo consultivo a nivel de sesión, por lo que se libera al finalizar la transacción.
Ejecutar y verificar
Inicie la aplicación en el puerto3115:
DELETE devuelve 204 No Content, por lo que su línea aparece vacía.
Compruebe que la sesión de base de datos de la aplicación usa TLS:
guide_dotnet y, a continuación, public, y haga clic en la tabla Todos. EF Core usa los nombres de clase y de propiedad como identificadores entre comillas, por lo que la tabla se llama "Todos" y las columnas son "Id", "Title", etc. La tabla contiene la fila restante:
Usar PgBouncer
Npgsql abre hasta 100 conexiones por cada instancia de la aplicación (Maximum Pool Size). Si entre todas las instancias se acercan al límite de conexiones de Postgres, conecte la aplicación a través del PgBouncer integrado. Seleccione via PgBouncer en el modal Conectar y cambie el puerto de la cadena de conexión a 6432:
- Sentencias preparadas: EF Core no prepara sentencias, y la preparación automática de Npgsql está desactivada de forma predeterminada (
Max Auto Prepare=0), por lo que las consultas usan sentencias sin nombre, que funcionan a través de PgBouncer. Mantenga esta configuración. A través de PgBouncer, las sentencias preparadas medianteMax Auto PrepareoNpgsqlCommand.Preparefallan de forma intermitente con08P01: prepared statement did not exist(No Reset On Close=truelo evita) y, si una migración cambia el tipo de una columna, siguen fallando concached plan must not change result type, incluso en conexiones nuevas. Si necesita sentencias preparadas, conéctese directamente. - Estado de la sesión: la configuración establecida con
SET, incluidosearch_path, no se conserva entre transacciones. Use en su lugarSET LOCALdentro de una transacción. PgBouncer rechaza las palabras claveSearch PathyOptionsde la cadena de conexión conunsupported startup parameter;TimezoneyApplication Namesí funcionan. - Migraciones:
dotnet ef database updatetambién funciona a través de PgBouncer, ya que el bloqueo de migración es un bloqueo de tabla que se libera al finalizar su transacción. - Comprobación de TLS:
pg_stat_ssldescribe la conexión entre PgBouncer y Postgres, por lo que/db/tlsdevuelvenone. La conexión de su aplicación a PgBouncer se sigue verificando: con un certificado de CA incorrecto, falla igual que antes.
Próximos pasos
- Conexión: cadenas de conexión, PgBouncer y TLS
- Configuración: parámetros de Postgres y PgBouncer, como
max_connections - Réplicas de lectura: envíe consultas de solo lectura a una réplica
- Seguridad: listas de acceso por IP y redes privadas