Prérequis
- Le SDK .NET 10. Ce guide a été testé avec le SDK .NET 10.0.401, EF Core 10.0.12 et
Npgsql.EntityFrameworkCore.PostgreSQL10.0.3 (Npgsql 10.0.3). - Un compte ClickHouse Cloud
psql, pour créer la base de données. Vous pouvez également exécuter le statementCREATE DATABASEdans la console SQL.
Créer un service ClickHouse Managed Postgres
Dans la console ClickHouse Cloud, cliquez sur New service et sélectionnez Postgres. L’instance est prête en quelques minutes. Pour une présentation pas à pas, consultez le guide de démarrage rapide.Obtenir vos informations de connexion
Cliquez sur Connect dans la barre latérale gauche de votre service. Laissez Directly sélectionné, activez Use SSL, puis copiez le mot de passe et le nom d’hôte du serveur. Cliquez ensuite sur Download CA certificate. Vous pouvez également télécharger le certificat plus tard depuis Settings → CA Certificate. Ce certificat est propre à votre instance : il permet à Npgsql de vérifier qu’il communique bien avec votre serveur. Dans ce guide, l’application comme les migrations EF Core se connectent directement à Postgres sur le port5432. Une application ASP.NET Core est un processus de longue durée, et Npgsql y gère déjà un pool de connexions (jusqu’à 100 par chaîne de connexion par défaut) ; un second pooler est donc inutile. Si vous exécutez de nombreuses instances de l’application, consultez Utiliser PgBouncer.
La fenêtre modale Connect ne propose pas d’onglet .NET, et Npgsql n’accepte pas l’URL postgresql:// de l’onglet url : il utilise des chaînes de connexion au format Keyword=Value. Reprenez les valeurs de l’URL et faites-les correspondre aux mots-clés Npgsql :
Configurer le projet
Créez un projet ASP.NET Core, ajoutez le fournisseur Npgsql pour EF Core ainsi que le paquet EF Core Design (outils de conception), puis installez l’outil en ligne de commandedotnet ef :
Configurer la connexion
Déplacez le certificat de CA téléchargé dans le répertoire du projet et renommez-le enca-certificate.pem.
Créez une base de données pour l’application. Remplacez <PASSWORD> et l’hôte par les valeurs affichées dans la fenêtre modale Connect :
appsettings.json ni dans le gestionnaire de versions :
Development, que dotnet run et dotnet ef utilisent par défaut. En production, définissez plutôt la variable d’environnement ConnectionStrings__TodoDb.
Avec SSL Mode=VerifyFull, Npgsql vérifie que le certificat du serveur est signé par la CA indiquée dans Root Certificate et qu’il correspond au nom d’hôte. Npgsql résout un path Root Certificate relatif par rapport au répertoire de travail courant, c’est-à-dire le répertoire du projet lorsque vous utilisez dotnet run et dotnet ef. Utilisez un path absolu si vous lancez l’application depuis un autre emplacement.
Si la CA est incorrecte ou absente, ou si l’hôte ne correspond pas au certificat (par exemple, lorsque vous vous connectez via une adresse IP), la connexion échoue avec
Exception while performing SSL handshake et l’erreur interne The remote certificate was rejected by the provided RemoteCertificateValidationCallback. Si le fichier Root Certificate n’existe pas, l’erreur interne est Could not find file. Notez également que :- Par défaut, Npgsql utilise
SSL Mode=Prefer, etSSL Mode=Requirene vérifie pas non plus le certificat, même si vous définissezRoot Certificate. Définissez toujoursSSL Mode=VerifyFull. - Npgsql lit les variables d’environnement
PGSSLROOTCERTetPGPASSWORD, mais pasPGHOSTniPGSSLMODE. Les variables de l’onglet env de la fenêtre modale Connect ne suffisent donc pas à elles seules.
Définir le modèle
Créez le fichierTodo.cs contenant la classe d’entité :
Todo.cs
TodoDb.cs contenant le DbContext :
TodoDb.cs
Program.cs. Ce code enregistre TodoDb auprès du fournisseur Npgsql et associe un endpoint à chaque opération. Dans une application existante, seul l’appel à AddDbContext avec UseNpgsql est nécessaire :
Program.cs
/db/tls lit pg_stat_ssl pour la session de base de données de l’application elle-même, ce qui vous permet de vérifier que la connexion est bien chiffrée.
Créer le schéma
Générez une migration à partir du modèle, puis appliquez-la :dotnet ef migrations add écrit la migration dans le dossier Migrations, et dotnet ef database update l’applique puis l’enregistre dans la table __EFMigrationsHistory. Lors de la première exécution, EF Core journalise l’échec d’un SELECT sur __EFMigrationsHistory avant de créer la table ; vous pouvez ignorer ce message.
Avant d’appliquer les migrations, EF Core acquiert un verrou afin que deux déploiements ne puissent pas migrer la même base de données simultanément. Avec Npgsql, ce verrou est un LOCK TABLE sur __EFMigrationsHistory au sein de la transaction de migration, et non un verrou consultatif (advisory lock) au niveau de la session ; il est donc libéré à la fin de la transaction.
Exécuter et vérifier
Démarrez l’application sur le port3115 :
DELETE renvoie 204 No Content : sa ligne est donc vide.
Vérifiez que la session de base de données de l’application utilise TLS :
guide_dotnet puis public, et cliquez sur la table Todos. EF Core utilise les noms de classes et de propriétés comme identifiants entre guillemets : la table s’appelle donc "Todos" et les colonnes "Id", "Title", etc. La table contient la ligne restante :
Utiliser PgBouncer
Npgsql ouvre jusqu’à 100 connexions par instance d’application (Maximum Pool Size). Si, cumulées, de nombreuses instances approchent la limite de connexions de Postgres, connectez plutôt l’application via le PgBouncer intégré. Sélectionnez via PgBouncer dans la fenêtre modale Connect, puis remplacez le port de la chaîne de connexion par 6432 :
- Requêtes préparées : EF Core ne prépare pas les statements, et la préparation automatique de Npgsql est désactivée par défaut (
Max Auto Prepare=0) ; les requêtes utilisent donc des statements non nommés, qui fonctionnent via PgBouncer. Conservez cette configuration. Via PgBouncer, les requêtes préparées issues deMax Auto Prepareou deNpgsqlCommand.Prepareéchouent de manière intermittente avec08P01: prepared statement did not exist(No Reset On Close=trueévite ce problème), et après une migration qui modifie le type d’une colonne, elles continuent d’échouer aveccached plan must not change result type, même sur de nouvelles connexions. Si vous avez besoin de requêtes préparées, connectez-vous directement. - État de session : les paramètres définis avec
SET, y comprissearch_path, ne sont pas conservés d’une transaction à l’autre. Utilisez plutôtSET LOCALau sein d’une transaction. PgBouncer rejette les mots-clés de chaîne de connexionSearch PathetOptionsavec l’erreurunsupported startup parameter;TimezoneetApplication Namefonctionnent. - Migrations :
dotnet ef database updatefonctionne également via PgBouncer, car le verrou de migration est un verrou de table qui est libéré à la fin de sa transaction. - Vérification TLS :
pg_stat_ssldécrit la connexion entre PgBouncer et Postgres ;/db/tlsrenvoie doncnone. La connexion de votre application à PgBouncer reste néanmoins vérifiée : un certificat de CA incorrect provoque le même échec.
Étapes suivantes
- Connexion : chaînes de connexion, PgBouncer et TLS
- Paramètres : paramètres Postgres et PgBouncer, comme
max_connections - Répliques en lecture : envoyer des requêtes en lecture seule vers une réplique
- Sécurité : listes d’accès IP et réseau privé