Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Microsoft.Data.SqlClient is the supported .NET data provider for SQL Server, Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics, and SQL database in Microsoft Fabric. It's distributed as a NuGet package, evolves independently of the .NET runtime, and replaces System.Data.SqlClient for new development. Use it to open connections, execute commands, process results, manage transactions, bulk load data, and use SQL Server-specific features from .NET applications.
Choose your starting point
- To set up a project and run your first query, start with Getting started with the SqlClient driver.
- To add the driver to a .NET project, go to Download Microsoft.Data.SqlClient.
- To connect to Azure SQL with passwordless authentication, start with Microsoft Entra authentication and Connection strings.
- To make an existing application resilient to transient failures, go to Configurable retry logic and High availability and disaster recovery.
- To move large data sets efficiently, go to Bulk copy operations.
- To migrate from
System.Data.SqlClient, start with Introduction to the Microsoft.Data.SqlClient namespace. - To diagnose a connection or query problem, go to SqlClient troubleshooting guide and Enable event source tracing.
Production baseline for Azure SQL
Use this snippet as a starting point for a production-oriented Azure SQL data access path. It reads the server and database names from IConfiguration, so the values come from whatever configuration providers the host wires up (appsettings.json, environment variables, Azure App Configuration, Key Vault-backed settings, and so on). The configuration combines Transport Layer Security (TLS), managed identity, idle-connection resiliency, initial-connect retry through configurable retry logic (CRL) with structured logging, command-level retry for transient errors that fire mid-query, and fast failover-group recovery.
For higher security and to support configuration across environments, keep connection information outside your code. In production, store connection information in your application's configuration system, and use Azure Key Vault for sensitive values. For more information, see Protect connection information.
The C# snippet in this article omits using directives and class wrappers for brevity.
public static void QuerySalesWithResilience(IConfiguration config, ILogger logger)
{
string server = config["Sql:Server"]
?? throw new InvalidOperationException("Missing configuration value 'Sql:Server'.");
string database = config["Sql:Database"]
?? throw new InvalidOperationException("Missing configuration value 'Sql:Database'.");
var builder = new SqlConnectionStringBuilder
{
DataSource = server,
InitialCatalog = database,
Authentication = SqlAuthenticationMethod.ActiveDirectoryManagedIdentity,
Encrypt = SqlConnectionEncryptOption.Strict, // TDS 8.0 encryption (SqlClient 5.0 and later versions; server must support it)
ConnectTimeout = 30, // per-attempt connect timeout in seconds
// Idle connection resiliency: reconnect a dropped idle connection after Open() succeeded.
// This is separate from the initial-connect retry provider defined next.
ConnectRetryCount = 3,
ConnectRetryInterval = 10,
MultiSubnetFailover = true, // recommended for any target; enables parallel connect
// ApplicationIntent = ApplicationIntent.ReadOnly, // uncomment to route to a readable secondary
};
// Retry the initial Open() on transient failures with exponential backoff and jitter.
// TransientErrors is null, so the provider uses the driver's built-in transient error list.
var openRetry = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(
new SqlRetryLogicOption
{
NumberOfTries = 5,
DeltaTime = TimeSpan.FromSeconds(3),
MaxTimeInterval = TimeSpan.FromSeconds(60),
});
openRetry.Retrying += (_, args) =>
{
Exception last = args.Exceptions[^1];
logger.LogWarning(
last,
"Retrying SQL connection to {Server}/{Database} (attempt {Attempt}) after {Delay}",
server, database, args.RetryCount, args.Delay);
};
// Retry commands that hit deadlocks, lock timeouts, or common Azure SQL transient errors
// mid-query on an established connection. Only attach this provider to commands whose
// effect is safe to repeat.
var commandRetry = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(
new SqlRetryLogicOption
{
NumberOfTries = 4,
DeltaTime = TimeSpan.FromSeconds(5),
MaxTimeInterval = TimeSpan.FromSeconds(30),
// Deadlock victim, lock-request timeout, and common Azure SQL transient errors.
TransientErrors = new[] { 1205, 1222, 10928, 10929, 40197, 40501, 40613, 49918 },
});
commandRetry.Retrying += (_, args) =>
{
Exception last = args.Exceptions[^1];
logger.LogWarning(
last,
"Retrying SQL command (attempt {Attempt}) after {Delay}",
args.RetryCount, args.Delay);
};
try
{
using var connection = new SqlConnection(builder.ConnectionString)
{
RetryLogicProvider = openRetry,
};
connection.Open();
using var command = new SqlCommand(
"SELECT TOP (100) SalesOrderId, OrderDate, TotalDue FROM Sales.SalesOrderHeader ORDER BY OrderDate DESC",
connection)
{
RetryLogicProvider = commandRetry,
CommandTimeout = 30,
};
using var reader = command.ExecuteReader();
while (reader.Read())
{
logger.LogInformation(
"Order {SalesOrderId} placed {OrderDate:d} total ${TotalDue:N2}",
reader.GetInt32(0), reader.GetDateTime(1), reader.GetDecimal(2));
}
}
catch (SqlException ex)
{
logger.LogError(
ex,
"Query against {Server}/{Database} failed after retries (SQL error {ErrorNumber})",
server, database, ex.Number);
throw;
}
}
This snippet is tuned for Azure SQL Database failover groups and Azure SQL Managed Instance.
Encrypt = SqlConnectionEncryptOption.Strict selects TDS 8.0 encryption. It requires Microsoft.Data.SqlClient 5.0 and later versions and a server that supports TDS 8.0 (SQL Server 2022 and later versions, Azure SQL Database, Azure SQL Managed Instance, and SQL database in Microsoft Fabric). Fall back to SqlConnectionEncryptOption.Mandatory when you connect to older servers.
ConnectRetryCount and ConnectRetryInterval enable idle connection resiliency: after Open() succeeds, the driver transparently reconnects a dropped idle connection on the next command. They don't retry the initial Open(). Initial-connect retries come from the openRetry provider assigned to SqlConnection.RetryLogicProvider. The two features are complementary.
The Retrying event on each provider fires before each retry attempt and carries the retry count, the delay before the next attempt, and the exceptions observed so far. Route it to ILogger or your telemetry pipeline to keep the retry loop visible in production.
Set MultiSubnetFailover = true for any SQL Server target. It selects a parallel-connect code path that completes login with the first responsive endpoint, avoiding the slow sequential per-IP walk that can otherwise stall connects to Azure SQL Database, Azure SQL Managed Instance, SQL database in Microsoft Fabric, availability group listeners, and failover cluster instances. On single-IP targets, the setting is safe. For more information, see High availability and disaster recovery and Disabling Transparent Network IP Resolution.
If the target is Azure SQL Database serverless with auto-pause enabled, raise ConnectTimeout to at least 60 seconds. An auto-paused database resumes on the first Open(), and the resume can take 30 to 60 seconds or more. Client-side timeouts surface as error -2, which isn't in the built-in transient error list, so openRetry won't rescue an Open() that times out mid-resume. The individual connect attempt must be long enough to cover the resume.
Command-level retry is the caller's decision, per command. Attach commandRetry to SqlCommand.RetryLogicProvider only when replaying the command is safe: reads, MERGE guarded by a natural key, upserts through a stored procedure, and other idempotent operations. The built-in command provider skips retry when a transaction is active, so multi-statement transactions must be retried by application code that can reopen the transaction. Setting TransientErrors replaces the driver's built-in error list; to extend the built-in baseline instead, use SqlConfigurableRetryFactory.BaselineTransientErrors (Microsoft.Data.SqlClient 7.0 and later).
For more information about each part of this configuration, see:
- Connection strings
- Microsoft Entra authentication
- Encryption and certificate validation
- Configurable retry logic
- High availability and disaster recovery
Key features
- Modern .NET support: Runs on current .NET and .NET Framework versions. For the per-version breakdown, see Support lifecycle.
- Encrypted by default: TLS-encrypted connections with
Encrypt=trueas the default. SetEncrypt=Strictfor TDS 8.0 encryption on Microsoft.Data.SqlClient 5.0 and later. - Microsoft Entra ID authentication: Passwordless connections with managed identity, service principal, interactive, integrated, default credential chain, and access-token flows.
- Kerberos and NTLM: Integrated Windows authentication for on-premises Active Directory and legacy scenarios.
- Always Encrypted: Client-side encryption for sensitive columns, with optional secure enclaves for in-place operations.
- Bulk copy: High-throughput inserts with SqlBulkCopy.
- Connection resiliency: Built-in connection retries (
ConnectRetryCountandConnectRetryInterval) plus opt-in configurable retry logic for connections and commands. - Rich SQL Server data types:
datetimeoffset,sql_variant, JSON, vector, spatial, XML, and table-valued parameters. - Diagnostics: Event source tracing, diagnostic counters, provider statistics, and a dedicated troubleshooting guide.
Get started
| Article | Description |
|---|---|
| Getting started with the SqlClient driver | Set up a project, create a database, connect, query, and add connection resiliency. |
| Overview of the SqlClient driver | Learn how Microsoft.Data.SqlClient fits into ADO.NET. |
| Download Microsoft.Data.SqlClient | Install the NuGet package and find source releases. |
| Support lifecycle | Review supported driver versions and support dates. |
| Microsoft.Data.SqlClient namespace | Migrate from System.Data.SqlClient and review namespace differences. |
Configure and connect
| Article | Description |
|---|---|
| Connect to a data source | Open and manage connections to SQL Server and Azure SQL. |
| Connection strings | Configure server, database, authentication, encryption, and connection behavior. |
| Encryption and certificate validation | Configure encrypted connections and server certificate validation. |
| SQL Server connection pooling | Reuse physical connections efficiently. |
| Connection events | Respond to connection state and informational messages. |
Authenticate and secure
| Article | Description |
|---|---|
| SQL Server security | Review authentication, authorization, and application security guidance. |
| Microsoft Entra authentication | Connect with managed identity, service principal, password, and interactive flows. |
| Protect connection information | Keep credentials and connection settings out of application code. |
| Always Encrypted | Protect sensitive column values from the database system. |
| Always Encrypted with secure enclaves | Run rich operations on encrypted data with a secure enclave. |
Retrieve and update data
| Article | Description |
|---|---|
| Commands and parameters | Execute parameterized SQL statements and stored procedures. |
| DataAdapters and DataReaders | Stream result sets or populate disconnected data structures. |
| Transactions and concurrency | Use local and distributed transactions and concurrency controls. |
| Retrieve database schema information | Discover schema collections and restrictions. |
| Bulk copy operations | Load large data sets efficiently with SqlBulkCopy. |
| Table-valued parameters | Send multiple rows to a parameterized statement or stored procedure. |
| Asynchronous programming | Use asynchronous connection, command, and data operations. |
| Multiple Active Result Sets (MARS) | Interleave multiple batches on one connection. |
Data types
| Article | Description |
|---|---|
| ADO.NET data type mappings | Map common language runtime types to provider and SQL Server types. |
| SQL Server data types | Work with SQL Server-specific values and System.Data.SqlTypes types. |
| JSON data | Send and retrieve the SQL Server json data type. |
| Vector data | Send and retrieve vector values. |
| XML data | Read, write, and parameterize XML values. |
| Binary and large-value data | Stream and update binary, FILESTREAM, and large-value data. |
Reliability and diagnostics
| Article | Description |
|---|---|
| Configurable retry logic | Retry transient connection and command failures with bounded policies. |
| High availability and disaster recovery | Connect to availability group listeners and failover partners. |
| Diagnostic counters | Monitor active connections, pooled connections, and other driver metrics. |
| Enable event source tracing | Capture detailed driver events for diagnosis. |
| Data tracing | Trace ADO.NET operations and data access. |
| SqlClient troubleshooting guide | Diagnose common connection and driver problems. |
| Query notifications | Receive notifications when query results change. |
SQL Server features
| Article | Description |
|---|---|
| SQL Server features and ADO.NET | Browse SQL Server-specific features available through SqlClient. |
| LocalDB | Connect to SQL Server Express LocalDB instances. |
| Data discovery and classification | Read sensitivity classification metadata from result sets. |
Reference and resources
| Article | Description |
|---|---|
| Microsoft.Data.SqlClient API reference | Browse .NET API reference for the driver. |
| AppContext switches | Configure compatibility and security behavior. |
| Find additional SqlClient information | Find source code, support, and community resources. |