Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
SqlConnectionreprésente une connexion logique vers SQL Server, Azure SQL ou un autre point de terminaison compatible SQL Server pris en charge. Ouvrir l’objet obtient une connexion physique du pool de connexions lorsqu’une connexion est disponible. La fermer ou la jeter renvoie cette connexion physique au pool.
Utilisez des objets à durée SqlConnection de vie éphémère pour les unités de travail. Ne laissez pas une seule connexion globale ouverte pour l’application.
Construire la configuration de connexion
Chargez une chaîne de connexion depuis le système de configuration de l'application. À utiliser SqlConnectionStringBuilder lorsque le code doit valider ou ajouter des paramètres :
string configuredConnectionString =
configuration.GetConnectionString("Orders")
?? throw new InvalidOperationException(
"Connection string 'Orders' wasn't configured.");
var builder = new SqlConnectionStringBuilder(configuredConnectionString)
{
ApplicationName = "Orders.Api",
};
Créez le SqlConnection à partir de builder.ConnectionString. Ne concaténez pas les données saisies par l’utilisateur à la chaîne de caractères. Pour les patrons d’authentification, le stockage sécurisé et la syntaxe, voir Chaînes de connexion.
Ouvrir et fermer les connexions
Appelez Open du code synchrone ou OpenAsync en code asynchrone. Ouvrir une nouvelle connexion logique pour chaque opération indépendante :
public static async Task<string?> LoadOrderStatusAsync(
string connectionString,
int orderId,
CancellationToken cancellationToken)
{
await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync(cancellationToken);
const string sql = """
SELECT Status
FROM Sales.Orders
WHERE OrderId = @orderId;
""";
using var command =
new SqlCommand(sql, connection) { CommandTimeout = 30 };
command.Parameters.Add(
new SqlParameter("@orderId", SqlDbType.Int) { Value = orderId });
object? value =
await command.ExecuteScalarAsync(cancellationToken);
return value is null or DBNull ? null : (string)value;
}
L’instruction await using élimine la connexion en cas de succès, d’erreur ou d’annulation. Lorsque le pooling de connexions est activé, la libération réinitialise normalement la connexion physique et la remet dans le pool au lieu de fermer son socket réseau.
Éliminez les lecteurs et commandes avant la connexion qui les possède. Ne comptez pas sur la collecte des ordures ou un Finalizer pour rétablir les connexions à la piscine.
Utiliser des API asynchrones
Utilisez des appels asynchrones pour le travail de base de données en réseau dans les serveurs web, les services, les interfaces utilisateur et les travailleurs :
OpenAsync(cancellationToken)ExecuteNonQueryAsync(cancellationToken)ExecuteReaderAsync(cancellationToken)ExecuteScalarAsync(cancellationToken)ReadAsync(cancellationToken)
Tu n’as pas besoin de Asynchronous Processing=true. Microsoft. Data.SqlClient 4.0 et versions ultérieures ne prennent pas en charge ce mot-clé de chaîne de connexion.
Ne commencez pas une autre opération sur une connexion, une commande ou un lecteur avant la fin de l’opération asynchrone en cours.
Demande une annulation et des délais d’attente
Transmettez le CancellationToken de l'appelant à chaque appel asynchrone à la base de données. L’annulation demande au prestataire d’arrêter les travaux en attente, mais l’achèvement n’est pas garanti immédiatement. Continuez à utiliser des délais d’attente de connexion et de commande bornés.
Ces contrôles ont des péripéties distinctes :
| Contrôle | Scope |
|---|---|
Connect Timeout |
Établissement de connexion ou attente d’une connexion regroupée |
SqlCommand.CommandTimeout |
Exécution d’une commande |
CancellationToken |
Annulation d’une opération asynchrone à demande de l’appelant |
Un délai d’attente ou une annulation ne prouve pas que le serveur a annulé une opération. Utilisez une transaction lorsque plusieurs modifications doivent être validées ou annulées comme une seule unité, et prenez des décisions de nouvelle tentative en fonction de l’idempotence de l’opération et du résultat de la transaction.
Comprendre l’état de connexion
La State propriété renvoie un instantané issu de l’énumération ConnectionState .
| State | Meaning |
|---|---|
Closed |
La connexion logique n’est pas ouverte. |
Connecting |
Une opération ouverte est en cours. |
Open |
La connexion logique est ouverte. |
Ne l’utilisez State pas comme contrôle de santé avant chaque commande. Le réseau peut tomber en panne après n’importe quel contrôle. Exécutez l’opération et gérez l’exception qui en résulte.
Le pilote signale généralement les transitions de l’état fermé à l’état ouvert et inversement. Ne considérez pas Executing, Fetching ou Broken comme des phases du cycle de vie de l’application.
L’événement StateChange rapporte des transitions d’état. L’événement InfoMessage signale des messages d’information et des avertissements du serveur qui ne se transforment pas en exceptions. Utilisez ces événements pour le diagnostic, pas pour coordonner le travail simultané.
Ne partagez pas de connexion en même temps
SqlConnection, SqlCommand, SqlDataReader, et SqlTransaction ne supportent pas l’utilisation simultanée par plusieurs threads. Attribuez à chaque opération concurrente sa propre connexion et laissez le pool de connexions réutiliser les connexions physiques.
Multiple Active Result Sets (MARS) permet plusieurs lots actifs sur une même connexion dans les scénarios pris en charge. Cela ne rend pas les objets SqlClient sûrs en thread, et ajoute des règles de session et de transaction. Laissez-le désactivé sauf si une opération en a spécifiquement besoin.
N’enregistrez pas un type ouvert SqlConnection comme singleton dans l’injection de dépendances. Enregistrez la chaîne de connexion, un objet options immuable, ou une usine qui crée une nouvelle connexion.
Utilisez les transactions de manière délibérée
Une transaction locale appartient à sa connexion. Chaque commande de la transaction doit utiliser cette connexion et définir sa Transaction propriété.
await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync(cancellationToken);
await using SqlTransaction transaction =
(SqlTransaction)await connection.BeginTransactionAsync(cancellationToken);
using var command = new SqlCommand(sql, connection, transaction);
command.Parameters.Add(
new SqlParameter("@value", SqlDbType.Int) { Value = value });
await command.ExecuteNonQueryAsync(cancellationToken);
await transaction.CommitAsync(cancellationToken);
Si l’opération échoue avant CommitAsync, la suppression de la transaction l’annule. Gardez les transactions courtes. Ne faites pas d’appels réseau, d’interactions utilisateur ou de calculs sans lien tant qu’une transaction de base de données détient des verrous.
Lorsque System.Transactions.Transaction.Current est actif, Open et OpenAsync s’inscrivent automatiquement par défaut. Défini Enlist=false uniquement lorsque l’opération doit rester en dehors de la transaction ambiante.
Mesurez une connexion logique
Définissez StatisticsEnabled sur true pour collecter les statistiques du fournisseur pour un objet SqlConnection :
await using var connection = new SqlConnection(connectionString)
{
StatisticsEnabled = true,
};
await connection.OpenAsync(cancellationToken);
connection.ResetStatistics();
using var command = new SqlCommand(sql, connection);
await command.ExecuteNonQueryAsync(cancellationToken);
System.Collections.IDictionary statistics =
connection.RetrieveStatistics();
long roundTrips =
Convert.ToInt64(statistics["ServerRoundtrips"]);
RetrieveStatistics renvoie un instantané.
ResetStatistics démarre une nouvelle délimitation de mesure. Réglé StatisticsEnabled=false pour arrêter la collecte ; les valeurs collectées jusqu’à présent restent disponibles. Les statistiques sont par objet de connexion et ajoutent de la surcharge, donc activez-les pour un diagnostic ciblé plutôt que pour chaque demande de production.
Pour les mesures de pool et de connexion à l’échelle du processus, utilisez des compteurs de diagnostic SqlClient.
Gérer les échecs de connexion
Interceptez SqlException au niveau d’une limite capable d’enregistrer l’échec, de le convertir ou de relancer l’opération. Enregistrer:
NumberStateClassClientConnectionId- Le nom de l’opération et les identifiants de serveur et de base de données configurés
Ne consignez pas la chaîne de connexion, le mot de passe, le secret client ou le jeton d'accès.
Éliminez une connexion cassée. Le pool supprime les connexions physiques invalides lorsqu’il les détecte. Si un identifiant, un jeton, un certificat, une cible DNS ou un serveur a changé, corrigez la configuration avant de réessayer.
Utilisez la logique de réessai bornée uniquement pour les défaillances transitoires. La réouverture initiale, la récupération de connexion inactive et la réévaluation par commande sont des mécanismes différents. Voir Logique de tentative configurable.