Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
SqlConnectionrepresenta una conexión lógica a SQL Server, Azure SQL u otro punto final compatible con SQL Server. Abrir el objeto obtiene una conexión física del conjunto de conexiones cuando hay una disponible. Cerrarlo o deshacerse de ella devuelve esa conexión física al pool.
Utiliza objetos SqlConnection de vida corta para unidades de trabajo. No dejes una sola conexión global abierta para la aplicación.
Construye la configuración de la conexión
Carga una cadena de conexión desde el sistema de configuración de la aplicación. Úsalo SqlConnectionStringBuilder cuando el código necesite validar o añadir ajustes:
string configuredConnectionString =
configuration.GetConnectionString("Orders")
?? throw new InvalidOperationException(
"Connection string 'Orders' wasn't configured.");
var builder = new SqlConnectionStringBuilder(configuredConnectionString)
{
ApplicationName = "Orders.Api",
};
Crea el SqlConnection a partir de builder.ConnectionString. No concatenes la entrada del usuario en la cadena. Para patrones de autenticación, almacenamiento seguro y sintaxis, véase Cadenas de conexión.
Abrir y cerrar conexiones
Llama Open a código síncrono o OpenAsync en código asincrónico. Abre una nueva conexión lógica para cada operación independiente:
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;
}
La await using instrucción elimina la conexión en caso de éxito, error o cancelación. Con el pooling activado, el descarte normalmente se reinicia y devuelve la conexión física en lugar de cerrar su socket de red.
Elimina los lectores y comandos antes que la conexión que los posee. No dependas de la recogida de basura ni de un finalizador para devolver las conexiones a la piscina.
Usar API asincrónicas
Utiliza llamadas asíncronas para trabajo de bases de datos vinculadas a red en servidores web, servicios, interfaces de usuario y trabajadores:
OpenAsync(cancellationToken)ExecuteNonQueryAsync(cancellationToken)ExecuteReaderAsync(cancellationToken)ExecuteScalarAsync(cancellationToken)ReadAsync(cancellationToken)
No necesitas Asynchronous Processing=true. Microsoft.Data.SqlClient 4.0 y las versiones posteriores no admiten esa palabra clave de la cadena de conexión.
No inicies otra operación en una conexión, comando o lector antes de que termine la operación asíncrona actual.
Solicita cancelaciones y tiempos de espera
Pasar el CancellationToken del llamador en todas las llamadas asíncronas a la base de datos. La cancelación pide al proveedor que detenga el trabajo pendiente, pero no se garantiza que se complete de forma inmediata. Sigue usando tiempos de espera limitados para la conexión y los comandos.
Estos controles tienen ámbitos separados:
| Control | Alcance |
|---|---|
Connect Timeout |
Establecimiento de conexión o espera de una conexión agrupada |
SqlCommand.CommandTimeout |
Ejecución de un comando |
CancellationToken |
Cancelación solicitada por el llamante de una operación asíncrona |
Un tiempo de espera o cancelación no prueba que el servidor haya revertido una operación. Utiliza una transacción cuando varios cambios deban confirmarse o revertirse como una única unidad, y toma decisiones sobre los reintentos en función de la idempotencia de la operación y del resultado de la transacción.
Entender el estado de la conexión
La State propiedad devuelve una instantánea de la ConnectionState enumeración.
| Estado | Meaning |
|---|---|
Closed |
La conexión lógica no está abierta. |
Connecting |
Se está llevando a cabo una operación abierta. |
Open |
La conexión lógica está abierta. |
No uses State como comprobación de estado antes de cada comando. La red puede fallar tras cualquier comprobación. Ejecuta la operación y gestiona la excepción resultante.
El conductor normalmente informa de transiciones de cerrado a abierto y de abierto a cerrado. No confíes en observar Executing, Fetching ni Broken como fases del ciclo de vida de la aplicación.
El StateChange evento informa de transiciones de estado. El evento InfoMessage notifica mensajes informativos y advertencias del servidor que no llegan a convertirse en excepciones. Utiliza estos eventos para diagnósticos, no para coordinar trabajos concurrentes.
No compartas una conexión simultáneamente
SqlConnection, SqlCommand, SqlDataReader, y SqlTransaction no soportan el uso simultáneo por múltiples hilos. Asignar a cada operación concurrente su propia conexión y dejar que la agrupación de conexiones reutilice las conexiones físicas.
Múltiples Conjuntos de Resultados Activos (MARS) permite múltiples lotes activos en una misma conexión en escenarios compatibles. No hace que los objetos SqlClient sean seguros para hilos, y añade reglas de sesión y transacciones. Déjalo desactivado a menos que una operación lo requiera específicamente.
No registres un open SqlConnection como un singleton en la inyección de dependencia. Registre la cadena de conexión, un objeto de opciones inmutable o una fábrica que crea una nueva conexión.
Usa las transacciones de forma deliberada
Una transacción local pertenece a su conexión. Cada comando en la transacción debe usar esa conexión y establecer su Transaction propiedad.
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 la operación falla antes de CommitAsync, eliminar la transacción la revierte. Mantén las transacciones cortas. No hagas llamadas de red, interacción con el usuario ni cálculos no relacionados mientras una transacción de base de datos tiene bloqueos.
Cuando System.Transactions.Transaction.Current está activo, Open y OpenAsync se registran automáticamente de forma predeterminada. Se establece Enlist=false solo cuando la operación debe permanecer fuera de la transacción ambiental.
Mida una conexión lógica
Establezca StatisticsEnabled en true para recopilar estadísticas del proveedor para un objeto 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 devuelve una instantánea.
ResetStatistics Inicia un nuevo límite de medición. Configura StatisticsEnabled=false para dejar de recopilar; los valores recopilados hasta ahora siguen disponibles. Las estadísticas son por objeto de conexión y añaden sobrecarga, así que habilitalas para un diagnóstico dirigido en lugar de cada solicitud de producción.
Para mediciones de pool y conexión a nivel de proceso, utiliza contadores de diagnóstico SqlClient.
Manejar fallos de conexión
Atrapa SqlException en un límite que pueda registrar, trasladar o intentar repetir el fallo. Grabar:
NumberStateClassClientConnectionId- El nombre de la operación y los identificadores configurados del servidor y la base de datos
No registres la cadena de conexión, la contraseña, el secreto del cliente ni el token de acceso.
Deshazte de una conexión rota. El pool elimina conexiones físicas inválidas cuando las detecta. Si una credencial, token, certificado, destino DNS o servidor cambió, corrige la configuración antes de intentarlo de nuevo.
Utiliza lógica de reintento acotada solo para fallos transitorios. El reintento en la apertura inicial, la recuperación de conexiones inactivas y el reintento de comandos son mecanismos diferentes. Consulta lógica de reintentos configurable.