| applyTo | ** |
|---|
This repository contains the official Microsoft ADO.NET data provider for SQL Server. The driver is built from a single unified project that multi-targets all supported frameworks.
src/
├── Microsoft.Data.SqlClient/
│ ├── add-ons/ # Azure Key Vault provider
│ ├── netcore/ # ⚠️ LEGACY - being phased out
│ │ └── ref/ # Reference assemblies for .NET Core/.NET
│ ├── netfx/ # ⚠️ LEGACY - being phased out
│ │ └── ref/ # Reference assemblies for .NET Framework
│ ├── ref/ # Shared reference assembly files
│ ├── src/ # ✅ PRIMARY - Unified source for all platforms
│ │ ├── Microsoft.Data.SqlClient.csproj # Multi-target project file
│ │ ├── Interop/ # P/Invoke and native interop
│ │ ├── Microsoft/Data/SqlClient/ # Main driver source
│ │ ├── Resources/ # Embedded resources and strings
│ │ ├── System/ # System-level helpers
│ │ └── TypeForwards.netcore.cs # Type forwarding for .NET Core
│ └── tests/ # All test projects
│ ├── FunctionalTests/ # Tests without SQL Server dependency
│ ├── ManualTests/ # Integration tests requiring SQL Server
│ └── UnitTests/ # Unit tests
├── Microsoft.Data.SqlClient.Extensions/ # Extension libraries
└── Microsoft.SqlServer.Server/ # SQL Server CLR types
The driver is transitioning away from separate netfx/ and netcore/ project files toward a single unified project at src/Microsoft.Data.SqlClient/src/Microsoft.Data.SqlClient.csproj. This project targets the modern .NET TFMs on every host and conditionally adds .NET Framework on Windows:
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
<TargetFrameworks Condition="'$(NormalizedTargetOs)' == 'windows_nt'">$(TargetFrameworks);net462</TargetFrameworks>All new code MUST go into src/Microsoft.Data.SqlClient/src/. Do NOT add files to the legacy netcore/src/ or netfx/src/ directories.
The netcore/ and netfx/ directories are legacy artifacts from the old dual-project model:
netcore/src/andnetfx/src/— DEPRECATED. These contain legacy project files that are being phased out. Do not add new code here.netcore/ref/andnetfx/ref/— STILL ACTIVE. Reference assemblies remain in these directories and define the public API surface for each target framework.
The unified project uses a TargetOs MSBuild property to handle OS-specific compilation:
<!-- Automatic OS detection -->
<TargetOs Condition="... '.NETFramework'">Windows_NT</TargetOs> <!-- .NET Framework always targets Windows -->
<TargetOs Condition="'$(TargetOs)' == ''">$(OS)</TargetOs> <!-- .NET uses host OS by default -->This defines preprocessor constants:
_WINDOWS— Defined whenTargetOsisWindows_NT_UNIX— Defined whenTargetOsisUnix
NOTE: These constants are prefixed with
_(underscore) to avoid conflict with .NET 5+ built-in OS-specific target framework preprocessor flags.
The driver supports both .NET Framework and .NET Core/.NET 8+. Platform-specific code uses file suffixes:
.netfx.cs— .NET Framework only (compiled when targetingnet462).netcore.cs— .NET Core/.NET only (compiled when targetingnet8.0/net9.0).windows.cs— Windows only (compiled when_WINDOWSis defined).unix.cs— Unix/Linux/macOS only (compiled when_UNIXis defined)
All platform-specific files live in the unified src/ directory alongside shared code.
When writing code that differs by platform, use these preprocessor directives:
| Directive | When to Use |
|---|---|
#if NETFRAMEWORK |
Code for .NET Framework (net462) only |
#if NET |
Code for .NET Core/.NET 8+ only |
#if _WINDOWS |
Code for Windows OS (any framework) |
#if _UNIX |
Code for Unix/Linux/macOS OS (any framework) |
Guidelines:
- All code must compile for the TFMs supported by the current target OS:
net8.0/net9.0everywhere, plusnet462on Windows builds - Use
#if NETFRAMEWORKor#if NETfor framework-specific code paths - Use
#if _WINDOWSor#if _UNIXfor OS-specific code paths - Avoid APIs that don't exist on a target platform without conditional compilation
- Prefer
#if NETover#if NETCOREAPPfor .NET (net8.0/net9.0) code paths to keep conditions consistent
The unified project uses conditional ItemGroup elements for dependencies:
- net462: References
System.Configuration,System.EnterpriseServices,System.Transactions, plusMicrosoft.Data.SqlClient.SNInative package - net8.0/net9.0: References
Microsoft.Data.SqlClient.SNI.runtime,System.Configuration.ConfigurationManager,Microsoft.SqlServer.Server - Shared:
Azure.Core,Azure.Identity,Microsoft.Bcl.Cryptography,Microsoft.Extensions.Caching.Memory,Microsoft.IdentityModel.*,System.Security.Cryptography.Pkcs
The ref/ directories define the public API surface:
netcore/ref/— Public APIs for .NET Core/.NET (includesMicrosoft.Data.SqlClient.cs,Microsoft.Data.SqlClient.Manual.cs)netfx/ref/— Public APIs for .NET Framework (includesMicrosoft.Data.SqlClient.cs)ref/— Shared reference assembly files (e.g.,Microsoft.Data.SqlClient.Batch.cs,Microsoft.Data.SqlClient.Batch.NetCoreApp.cs)
IMPORTANT: Any public API changes MUST update the corresponding reference assembly in the appropriate ref/ directory.
Build artifacts are organized by reference mode, configuration, OS, and framework:
artifacts/Microsoft.Data.SqlClient/{ReferenceType}-{Configuration}/{NormalizedTargetOs}/{TargetFramework}/
ReferenceType is a first-class build dimension in this branch. Local and CI builds may run in:
Projectmode — sibling packages referenced as projectsPackagemode — sibling packages restored from locally produced NuGet packages
Two implementations exist:
- Cross-platform managed code implementation
- Located in
src/Microsoft/Data/SqlClient/ManagedSni/ - Used by default on Unix platforms
- Can be opted into on Windows via
UseManagedSNIOnWindowsconnection string option
- Windows-only native library (C++)
- Shipped as separate NuGet packages:
Microsoft.Data.SqlClient.SNI— For .NET Framework (net462)Microsoft.Data.SqlClient.SNI.runtime— For .NET Core/.NET on Windows
- Provides optimal performance on Windows
Entry point for database connectivity. Manages:
- Connection string parsing (via
SqlConnectionStringBuilder) - Connection pooling integration
- Transaction enlistment (local and distributed)
- Authentication (SQL, Windows, Entra ID)
Executes SQL statements and stored procedures:
- Batch execution support (
SqlBatch) - Async methods (
ExecuteReaderAsync,ExecuteNonQueryAsync, etc.) - Always Encrypted parameter encryption
- Query metadata caching
Core TDS protocol implementation:
- Packet encoding/decoding
- Protocol state machine
- Feature negotiation
- Token parsing (see
TdsEnums.csfor token definitions)
Located in ConnectionPool/:
ChannelDbConnectionPool— Modern async-friendly pool using System.Threading.ChannelsWaitHandleDbConnectionPool— Traditional pool using wait handles- Pool groups manage pools for different connection strings
Located in SSPI/ and authentication-related files:
- Windows Authentication (SSPI/Kerberos)
- SQL Server Authentication
- Entra ID authentication modes
Column-level encryption implementation:
- Certificate-based key providers
- Azure Key Vault integration (add-ons package)
- Secure enclave support (VBS, SGX)
| Package | Description |
|---|---|
| Microsoft.Data.SqlClient | Main driver package |
| Microsoft.Data.SqlClient.SNI | Native SNI for .NET Framework |
| Microsoft.Data.SqlClient.SNI.runtime | Native SNI runtime for .NET |
| Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider | AKV integration |
| Microsoft.SqlServer.Server | SQL CLR types |
- .NET Framework 4.6.2+
- .NET 8.0+
- See
Directory.Packages.propsfor centralized package version management