diff --git a/.editorconfig b/.editorconfig
index f5c888e04a..db85dde7fd 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -140,6 +140,9 @@ dotnet_diagnostic.CA1063.severity = silent
# CA2100: Review SQL queries for security vulnerabilities
dotnet_diagnostic.CA2100.severity = silent
+# CA1416: Validate platform compatibility
+dotnet_diagnostic.CA1416.severity = silent
+
[*.{csproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
indent_size = 2
@@ -163,3 +166,6 @@ end_of_line = crlf
# Analyzers
dotnet_code_quality.ca1802.api_surface = private, internal
+
+[*.cs]
+dotnet_code_quality.CA2100.excluded_type_names_with_derived_types = Microsoft.Data.SqlClient.ManualTesting.Tests.*
diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md
index 41ff39445d..47cacc9fb7 100644
--- a/BUILDGUIDE.md
+++ b/BUILDGUIDE.md
@@ -5,6 +5,7 @@ This document provides all the necessary details to build the driver and run tes
## Visual Studio Pre-Requisites
This project should be built with Visual Studio 2019+ for the best compatibility. The required set of components are provided in the below file:
+
- **Visual Studio 2019** with imported components: [VS19Components](/tools/vsconfig/VS19Components.vsconfig)
Once the environment is setup properly, execute the desired set of commands below from the _root_ folder to perform the respective operations:
@@ -14,137 +15,217 @@ Once the environment is setup properly, execute the desired set of commands belo
```bash
# Default Build Configuration:
-> msbuild
+msbuild
# Builds the driver for the Client OS in 'Debug' Configuration for 'AnyCPU' platform.
-# Both .NET Framework (NetFx) and .NET Core drivers are built by default (as supported by Client OS).
+# Both .NET Framework (NetFx) and .NET (CoreFx) drivers are built by default (as supported by Client OS).
```
```bash
-> msbuild /p:Configuration=Release
-# Builds the driver in 'Release' Configuration.
+msbuild -t:clean
+# Cleans all build directories.
```
```bash
-> msbuild /p:Platform=x86
-# Builds the .NET Framework (NetFx) driver for Win32 (x86) platform on Windows.
+msbuild -p:Configuration=Release
+# Builds the driver in 'Release' Configuration for `AnyCPU` platform.
```
```bash
-> msbuild /t:clean
-# Cleans all build directories.
-```
-
-```bash
-> msbuild /t:restore
+msbuild -t:restore
# Restores Nuget Packages.
```
```bash
-> msbuild /t:BuildAllConfigurations
+msbuild -t:BuildAllConfigurations
# Builds the driver for all target OSes and supported platforms.
```
```bash
-> msbuild /p:BuildNetFx=false
+msbuild -p:BuildNetFx=false
# Skips building the .NET Framework (NetFx) Driver on Windows.
# On Unix the netfx driver build is automatically skipped.
```
```bash
-> msbuild /p:OSGroup=Unix
+msbuild -p:OSGroup=Unix
# Builds the driver for the Unix platform.
```
```bash
-> msbuild /t:BuildNetCoreAllOS
-# Builds the .NET Core driver for all Operating Systems.
+msbuild -t:BuildNetCoreAllOS
+# Builds the .NET driver for all Operating Systems.
```
## Building Tests
```bash
-> msbuild /t:BuildTestsNetCore
-# Build the tests for the .NET Core driver. Default .NET Core version is 2.1.
+msbuild -t:BuildTestsNetCore
+# Build the tests for the .NET driver in 'Debug' Configuration. Default .NET version is 6.0.
+```
+
+```bash
+msbuild -t:BuildTestsNetFx
+# Build the tests for the .NET Framework (NetFx) driver in 'Debug' Configuration. Default .NET Framework version is 4.6.2.
+```
+
+```bash
+msbuild -t:BuildTestsNetCore -p:TestSet=1
+# Build a subset of the manual tests. Valid values: '1', '2', '3', 'AE'. Omit to build all tests.
+```
+
+## Running Tests
+
+There are 2 ways to run tests, using MsBuild or Dotnet SDK.
+
+### Running from Build.proj
+
+```bash
+msbuild -t:RunFunctionalTests
+# Run all functional tests in Debug configuration for *default* target framework (.NET 6.0).
```
```bash
-> msbuild /t:BuildTestsNetFx
-# Build the tests for the .NET Framework (NetFx) driver. Default .NET Framework version is 4.6.
+msbuild -t:RunManualTests
+# Run all manual tests in Debug configuration for *default* target framework (.NET 6.0).
```
-## Run Functional Tests
+```bash
+msbuild -t:RunTests -p:configuration=Release
+# Run both functional and manual tests in Release configuration for *default* target framework (.NET 6.0).
+```
+
+```bash
+msbuild -t:RunTests -p:configuration=Release -p:DotnetPath=C:\net6-win-x86\
+# Run both functional and manual tests in Release configuration for *default* target framework (.NET 6.0) against the installed dotnet tool in the provided path.
+```
+
+To specify custom target framework, use `TF` property:
+
+```bash
+msbuild -t:RunTests -p:configuration=Release -p:TF=net7.0
+msbuild -t:RunTests -p:configuration=Release -p:TF=net48
+# Runs tests for specified target framework.
+# TargetNetCoreVersion and TargetNetFxVersion are not to be used with TF property, they will take precedence over TF if provided.
+```
+
+To capture test and code coverage results in a custom directory:
+
+```bash
+msbuild -t:RunTests -p:ResultsDirectory=MyDirectory
+# Runs tests with test and code coverage results placed in provided results directory.
+# Default results directory is "TestResults".
+```
+
+Other properties can be set alongside as needed.
+
+### Running using Dotnet SDK (traditional)
+
+#### Run Functional Tests
+
+- Windows (`netfx x86`):
-Windows (`netfx x86`):
```bash
-> dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
+dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x86" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
```
-Windows (`netfx x64`):
+- Windows (`netfx x64`):
+
```bash
-> dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
+dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
```
-Windows (`netcoreapp`):
+- AnyCPU:
+
+ Project reference only builds Driver with `AnyCPU` platform, and underlying process decides to run the tests with a compatible architecture (x64, x86, ARM64).
+
+ Windows (`netcoreapp`):
+
```bash
-> dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"
+dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"
```
-Unix (`netcoreapp`):
+ Unix (`netcoreapp`):
+
```bash
-> dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
+dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
```
-## Run Manual Tests
+#### Run Manual Tests
+
+### Pre-Requisites for running Manual tests
-### Pre-Requisites for running Manual tests:
Manual Tests require the below setup to run:
-* SQL Server with enabled Shared Memory, TCP and Named Pipes Protocols and access to the Client OS.
-* Databases "NORTHWIND" and "UdtTestDb" present in SQL Server, created using SQL scripts [createNorthwindDb.sql](tools/testsql/createNorthwindDb.sql) and [createUdtTestDb.sql](tools/testsql/createUdtTestDb.sql).
-* Make a copy of the configuration file [config.default.json](src/Microsoft.Data.SqlClient/tests/ManualTests/config.default.json) and rename it to `config.json`. Update the values in `config.json`:
-|Property|Description|Value|
-|------|--------|-------------------|
-|TCPConnectionString | Connection String for a TCP enabled SQL Server instance. | `Server={servername};Database={Database_Name};Trusted_Connection=True;` OR `Data Source={servername};Initial Catalog={Database_Name};Integrated Security=True;`|
-|NPConnectionString | Connection String for a Named Pipes enabled SQL Server instance.| `Server=\\{servername}\pipe\sql\query;Database={Database_Name};Trusted_Connection=True;` OR `Data Source=np:{servername};Initial Catalog={Database_Name};Integrated Security=True;`|
-|TCPConnectionStringHGSVBS | (Optional) Connection String for a TCP enabled SQL Server with Host Guardian Service (HGS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = HGS; Enclave Attestation Url = {AttestationURL};`|
-|AADAuthorityURL | (Optional) Identifies the OAuth2 authority resource for `Server` specified in `AADPasswordConnectionString` | `https://login.windows.net/`, where `` is the tenant ID of the Azure Active Directory (Azure AD) tenant |
-|AADPasswordConnectionString | (Optional) Connection String for testing Azure Active Directory Password Authentication. | `Data Source={server.database.windows.net}; Initial Catalog={Azure_DB_Name};Authentication=Active Directory Password; User ID={AAD_User}; Password={AAD_User_Password};`|
-|AADSecurePrincipalId | (Optional) The Application Id of a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. | {Application ID} |
-|AADSecurePrincipalSecret | (Optional) A Secret defined for a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. | {Secret} |
-|AzureKeyVaultURL | (Optional) Azure Key Vault Identifier URL | `https://{keyvaultname}.vault.azure.net/` |
-|AzureKeyVaultClientId | (Optional) "Application (client) ID" of an Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL`. Requires the key permissions Get, List, Import, Decrypt, Encrypt, Unwrap, Wrap, Verify, and Sign. | _{Client Application ID}_ |
-|AzureKeyVaultClientSecret | (Optional) "Client Secret" of the Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL` | _{Client Application Secret}_ |
-|SupportsLocalDb | (Optional) Whether or not a LocalDb instance of SQL Server is installed on the machine running the tests. |`true` OR `false`|
-|SupportsIntegratedSecurity | (Optional) Whether or not the USER running tests has integrated security access to the target SQL Server.| `true` OR `false`|
-|SupportsFileStream | (Optional) Whether or not FileStream is enabled on SQL Server| `true` OR `false`|
-|UseManagedSNIOnWindows | (Optional) Enables testing with Managed SNI on Windows| `true` OR `false`|
-|IsAzureSynpase | (Optional) When set to 'true', test suite runs compatible tests for Azure Synapse/Parallel Data Warehouse. | `true` OR `false`|
+- SQL Server with enabled Shared Memory, TCP and Named Pipes Protocols and access to the Client OS.
+- Databases "NORTHWIND" and "UdtTestDb" present in SQL Server, created using SQL scripts [createNorthwindDb.sql](tools/testsql/createNorthwindDb.sql) and [createUdtTestDb.sql](tools/testsql/createUdtTestDb.sql). To setup an Azure Database with "NORTHWIND" tables, use SQL Script: [createNorthwindAzureDb.sql](tools/testsql/createNorthwindAzureDb.sql).
+- Make a copy of the configuration file [config.default.json](src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json) and rename it to `config.json`. Update the values in `config.json`:
+
+ |Property|Description|Value|
+ |------|--------|-------------------|
+ |TCPConnectionString | Connection String for a TCP enabled SQL Server instance. | `Server={servername};Database={Database_Name};Trusted_Connection=True;` OR `Data Source={servername};Initial Catalog={Database_Name};Integrated Security=True;`|
+ |NPConnectionString | Connection String for a Named Pipes enabled SQL Server instance.| `Server=\\{servername}\pipe\sql\query;Database={Database_Name};Trusted_Connection=True;` OR `Data Source=np:{servername};Initial Catalog={Database_Name};Integrated Security=True;`|
+ |TCPConnectionStringHGSVBS | (Optional) Connection String for a TCP enabled SQL Server with Host Guardian Service (HGS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = HGS; Enclave Attestation Url = {AttestationURL};`|
+ |TCPConnectionStringAASVBS | (Optional) Connection String for a TCP enabled SQL Server with a VBS Enclave and using Microsoft Azure Attestation (AAS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = AAS; Enclave Attestation Url = {AttestationURL};`|
+ |TCPConnectionStringNoneVBS | (Optional) Connection String for a TCP enabled SQL Server with a VBS Enclave and using None Attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = NONE;`|
+ |TCPConnectionStringAASSGX | (Optional) Connection String for a TCP enabled SQL Server with a SGX Enclave and using Microsoft Azure Attestation (AAS) attestation protocol configuration. | `Server=tcp:{servername}; Database={Database_Name}; UID={UID}; PWD={PWD}; Attestation Protocol = AAS; Enclave Attestation Url = {AttestationURL};`|
+ |EnclaveEnabled | Enables tests requiring an enclave-configured server.|
+ |TracingEnabled | Enables EventSource related tests |
+ |AADAuthorityURL | (Optional) Identifies the OAuth2 authority resource for `Server` specified in `AADPasswordConnectionString` | `https://login.windows.net/`, where `` is the tenant ID of the Azure Active Directory (Azure AD) tenant |
+ |AADPasswordConnectionString | (Optional) Connection String for testing Azure Active Directory Password Authentication. | `Data Source={server.database.windows.net}; Initial Catalog={Azure_DB_Name};Authentication=Active Directory Password; User ID={AAD_User}; Password={AAD_User_Password};`|
+ |AADSecurePrincipalId | (Optional) The Application Id of a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. | {Application ID} |
+ |AADSecurePrincipalSecret | (Optional) A Secret defined for a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. | {Secret} |
+ |AzureKeyVaultURL | (Optional) Azure Key Vault Identifier URL | `https://{keyvaultname}.vault.azure.net/` |
+ |AzureKeyVaultTenantId | (Optional) The Azure Active Directory tenant (directory) Id of the service principal. | _{Tenant ID of Active Directory}_ |
+ |AzureKeyVaultClientId | (Optional) "Application (client) ID" of an Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL`. Requires the key permissions Get, List, Import, Decrypt, Encrypt, Unwrap, Wrap, Verify, and Sign. | _{Client Application ID}_ |
+ |AzureKeyVaultClientSecret | (Optional) "Client Secret" of the Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL` | _{Client Application Secret}_ |
+ |SupportsIntegratedSecurity | (Optional) Whether or not the USER running tests has integrated security access to the target SQL Server.| `true` OR `false`|
+ |LocalDbAppName | (Optional) If Local Db Testing is supported, this property configures the name of Local DB App instance available in client environment. Empty string value disables Local Db testing. | Name of Local Db App to connect to.|
+ |LocalDbSharedInstanceName | (Optional) If LocalDB testing is supported and the instance is shared, this property configures the name of the shared instance of LocalDB to connect to. | Name of shared instance of LocalDB. |
+ |FileStreamDirectory | (Optional) If File Stream is enabled on SQL Server, pass local directory path to be used for setting up File Stream enabled database. | `D:\\escaped\\absolute\\path\\to\\directory\\` |
+ |UseManagedSNIOnWindows | (Optional) Enables testing with Managed SNI on Windows| `true` OR `false`|
+ |DNSCachingConnString | Connection string for a server that supports DNS Caching|
+ |IsAzureSynpase | (Optional) When set to 'true', test suite runs compatible tests for Azure Synapse/Parallel Data Warehouse. | `true` OR `false`|
+ |EnclaveAzureDatabaseConnString | (Optional) Connection string for Azure database with enclaves |
+ |ManagedIdentitySupported | (Optional) When set to `false` **Managed Identity** related tests won't run. The default value is `true`. |
+ |IsManagedInstance | (Optional) When set to `true` **TVP** related tests will use on non-Azure bs files to compare test results. this is needed when testing against Managed Instances or TVP Tests will fail on Test set 3. The default value is `false`. |
+ |PowerShellPath | The full path to PowerShell.exe. This is not required if the path is present in the PATH environment variable. | `D:\\escaped\\absolute\\path\\to\\PowerShell.exe` |
+
+### Commands to run Manual Tests
+
+- Windows (`netfx x86`):
-Commands to run tests:
+```bash
+dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="x86" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
+ ```
+
+- Windows (`netfx x64`):
-Windows (`netfx x86`):
```bash
-> dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
+dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
```
-Windows (`netfx x64`):
+- Windows (`netfx`):
+
```bash
-> dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
+dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests"
```
-Windows (`netcoreapp`):
+- Windows (`netcoreapp`):
+
```bash
-> dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"
+dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests"
```
-Unix (`netcoreapp`):
+- Unix (`netcoreapp`):
+
```bash
-> dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
+dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
```
## Run A Single Test
+
```bash
-> dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "FullyQualifiedName=Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted.CspProviderExt.TestKeysFromCertificatesCreatedWithMultipleCryptoProviders"
+dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "FullyQualifiedName=Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted.CspProviderExt.TestKeysFromCertificatesCreatedWithMultipleCryptoProviders"
```
## Testing with Custom ReferenceType
@@ -158,82 +239,98 @@ Tests can be built and run with custom "Reference Type" property that enables di
> ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES ***************
> CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION
-> ```
-> > msbuild /p:configuration=Release
+>
+> ```bash
+> msbuild -p:configuration=Release
> ```
-### Building Tests:
+A non-AnyCPU platform reference can only be used with package and NetStandardPackage reference types. Otherwise, the specified platform will be replaced with AnyCPU in the build process.
-For .NET Core, all 4 reference types are supported:
+### Building Tests with Reference Type
+
+For .NET, all 4 reference types are supported:
```bash
-> msbuild /t:BuildTestsNetCore /p:ReferenceType=Project
+msbuild -t:BuildTestsNetCore -p:ReferenceType=Project
# Default setting uses Project Reference.
-> msbuild /t:BuildTestsNetCore /p:ReferenceType=Package
+msbuild -t:BuildTestsNetCore -p:ReferenceType=Package
-> msbuild /t:BuildTestsNetCore /p:ReferenceType=NetStandard
+msbuild -t:BuildTestsNetCore -p:ReferenceType=NetStandard
-> msbuild /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage
+msbuild -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage
```
For .NET Framework, below reference types are supported:
```bash
-> msbuild /t:BuildTestsNetFx /p:ReferenceType=Project
+msbuild -t:BuildTestsNetFx -p:ReferenceType=Project
# Default setting uses Project Reference.
-> msbuild /t:BuildTestsNetFx /p:ReferenceType=Package
+msbuild -t:BuildTestsNetFx -p:ReferenceType=Package
```
-### Running Tests:
+### Running Tests with Reference Type
Provide property to `dotnet test` commands for testing desired reference type.
-```
-dotnet test /p:ReferenceType=Project ...
+
+```bash
+dotnet test -p:ReferenceType=Project ...
```
-## Testing with Custom TargetFramework
+## Testing with Custom TargetFramework (traditional)
Tests can be built and run with custom Target Frameworks. See the below examples.
-### Building Tests:
+### Building Tests with custom target framework
```bash
-> msbuild /t:BuildTestsNetFx /p:TargetNetFxVersion=net461
+msbuild -t:BuildTestsNetFx -p:TargetNetFxVersion=net462
# Build the tests for custom TargetFramework (.NET Framework)
-# Applicable values: net46 (Default) | net461 | net462 | net47 | net471 net472 | net48
+# Applicable values: net462 (Default) | net47 | net471 net472 | net48 | net481
```
```bash
-> msbuild /t:BuildTestsNetCore /p:TargetNetCoreVersion=netcoreapp3.1
-# Build the tests for custom TargetFramework (.NET Core)
-# Applicable values: netcoreapp2.1 | netcoreapp2.2 | netcoreapp3.1 | netcoreapp5.0
+msbuild -t:BuildTestsNetCore -p:TargetNetCoreVersion=net6.0
+# Build the tests for custom TargetFramework (.NET)
+# Applicable values: net6.0 | net7.0
```
-### Running Tests:
+### Running Tests with custom target framework (traditional)
```bash
-> dotnet test /p:TargetNetFxVersion=net461 ...
+dotnet test -p:TargetNetFxVersion=net462 ...
# Use above property to run Functional Tests with custom TargetFramework (.NET Framework)
-# Applicable values: net46 (Default) | net461 | net462 | net47 | net471 net472 | net48
+# Applicable values: net462 (Default) | net47 | net471 net472 | net48 | net481
-> dotnet test /p:TargetNetCoreVersion=netcoreapp3.1 ...
-# Use above property to run Functional Tests with custom TargetFramework (.NET Core)
-# Applicable values: netcoreapp2.1 | netcoreapp2.2 | netcoreapp3.1 | netcoreapp5.0
+dotnet test -p:TargetNetCoreVersion=net6.0 ...
+# Use above property to run Functional Tests with custom TargetFramework (.NET)
+# Applicable values: net6.0 | net7.0
```
## Using Managed SNI on Windows
Managed SNI can be enabled on Windows by enabling the below AppContext switch:
-**"Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"**
+`Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows`
## Set truncation on for scaled decimal parameters
Scaled decimal parameter truncation can be enabled by enabling the below AppContext switch:
-**"Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal"**
+`Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal`
+
+## Enabling row version null behavior
+
+`SqlDataReader` returns a `DBNull` value instead of an empty `byte[]`. To enable the legacy behavior, you must enable the following AppContext switch on application startup:
+
+`Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior`
+
+## Suppressing TLS security warning
+
+When connecting to a server, if a protocol lower than TLS 1.2 is negotiated, a security warning is output to the console. This warning can be suppressed on SQL connections with `Encrypt = false` by enabling the following AppContext switch on application startup:
+
+`Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning`
## Debugging SqlClient on Linux from Windows
@@ -242,14 +339,17 @@ For enhanced developer experience, we support debugging SqlClient on Linux from
This project is also included in `docker-compose.yml` to demonstrate connectivity with SQL Server docker image.
To run the same:
+
1. Build the Solution in Visual Studio
2. Set `docker-compose` as Startup Project
3. Run "Docker-Compose" launch configuration.
4. You will see similar message in Debug window:
+
```log
Connected to SQL Server v15.00.4023 from Unix 4.19.76.0
The program 'dotnet' has exited with code 0 (0x0).
```
+
5. Now you can write code in [Program.cs](/src/Microsoft.Data.SqlClient/tests/DockerLinuxTest/Program.cs) to debug SqlClient on Linux!
### Troubleshooting Docker issues
@@ -259,6 +359,7 @@ There may be times where connection cannot be made to SQL Server, we found below
- Clear Docker images to create clean image from time-to-time, and clear docker cache if needed by running `docker system prune` in Command Prompt.
- If you face `Microsoft.Data.SqlClient.SNI.dll not found` errors when debugging, try updating the below properties in the netcore\Microsoft.Data.SqlClient.csproj file and try again:
+
```xml
Unixfalse
@@ -278,3 +379,17 @@ dotnet test --collect:"Code Coverage"
```bash
dotnet test --collect:"XPlat Code Coverage"
```
+
+## Run Performance Tests
+
+### Running Performance test project directly
+
+Project location from Root: `src\Microsoft.Data.SqlClient\tests\PerformanceTests\Microsoft.Data.SqlClient.PerformanceTests.csproj`
+Configure `runnerconfig.json` file with connection string and preferred settings to run Benchmark Jobs.
+
+```bash
+cd src\Microsoft.Data.SqlClient\tests\PerformanceTests
+dotnet run -c Release -f net6.0|net7.0
+```
+
+_Only "**Release** Configuration" applies to Performance Tests_
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dceaa7c412..129ca46b22 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,50 +4,584 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+## [Stable release 5.1.0] - 2023-01-19
+
+This update brings the below changes over the previous release:
+
+### Fixed
+
+- Fixed thread safety of transient error list in configurable retry logic. [#1882](https://github.com/dotnet/SqlClient/pull/1882)
+- Fixed deadlock when using SinglePhaseCommit with distributed transactions. [#1801](https://github.com/dotnet/SqlClient/pull/1801)
+- Fixed Dedicated Admin Connections (DAC) to localhost in managed SNI. [#1865](https://github.com/dotnet/SqlClient/pull/1865)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.1.0`. [#1889](https://github.com/dotnet/SqlClient/pull/1889) which includes fix for AppDomain crash in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418), TLS 1.3 Support, removal of ARM32 binaries, and support for the `ServerCertificate` option.
+- Code health improvements [#1867](https://github.com/dotnet/SqlClient/pull/1867) [#1849](https://github.com/dotnet/SqlClient/pull/1849)
+
+## [Preview Release 5.1.0-preview2.22314.2] - 2022-11-10
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v5.1.0-preview1
+
+- Dropped support for .NET Core 3.1. [#1704](https://github.com/dotnet/SqlClient/pull/1704) [#1823](https://github.com/dotnet/SqlClient/pull/1823)
+
+### Added
+
+- Added support for .NET 6.0. [#1704](https://github.com/dotnet/SqlClient/pull/1704)
+- Added support for `DateOnly` and `TimeOnly` for `SqlParameter` value and `GetFieldValue`. [#1813](https://github.com/dotnet/SqlClient/pull/1813)
+- Added support for TLS 1.3 for .NET Core and SNI Native. [#1821](https://github.com/dotnet/SqlClient/pull/1821)
+- Added `ServerCertificate` support for `Encrypt=Mandatory` or `Encrypt=Strict`. [#1822](https://github.com/dotnet/SqlClient/pull/1822)
+- Added Windows ARM64 support when targeting .NET Framework. [#1828](https://github.com/dotnet/SqlClient/pull/1828)
+
+### Fixed
+
+- Fixed memory leak regression from [#1781](https://github.com/dotnet/SqlClient/pull/1781) using a `DisposableTemporaryOnStack` struct. [#1818](https://github.com/dotnet/SqlClient/pull/1818)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.1.0-preview2.22311.2`. [#1831](https://github.com/dotnet/SqlClient/pull/1831) which includes the fix for the TLS 1.3 timeout and double handshake issue, removal of ARM32 binaries, and support for the `ServerCertificate` option. [#1822](https://github.com/dotnet/SqlClient/issues/1822)
+- Reverted "Excluding unsupported TLS protocols" for issue [#1151](https://github.com/dotnet/SqlClient/issues/1151) (i.e. removed `Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS`) by adding support for TLS 1.3. [#1824](https://github.com/dotnet/SqlClient/issues/1824)
+- Code health improvements [#1812](https://github.com/dotnet/SqlClient/pull/1812) [#1520](https://github.com/dotnet/SqlClient/pull/1520)
+
+## [Preview Release 5.1.0-preview1.22279.3] - 2022-10-19
+
+This update brings the below changes over the previous release:
+
+### Fixed
+
+- Fixed `ReadAsync()` behavior to register Cancellation token action before streaming results. [#1781](https://github.com/dotnet/SqlClient/pull/1781)
+- Fixed `NullReferenceException` when assigning `null` to `SqlConnectionStringBuilder.Encrypt`. [#1778](https://github.com/dotnet/SqlClient/pull/1778)
+- Fixed missing `HostNameInCertificate` property in .NET Framework Reference Project. [#1776](https://github.com/dotnet/SqlClient/pull/1776)
+- Fixed async deadlock issue when sending attention fails due to network failure. [#1766](https://github.com/dotnet/SqlClient/pull/1766)
+- Fixed failed connection requests in ConnectionPool in case of PoolBlock. [#1768](https://github.com/dotnet/SqlClient/pull/1768)
+- Fixed hang on infinite timeout and managed SNI. [#1742](https://github.com/dotnet/SqlClient/pull/1742)
+- Fixed Default UTF8 collation conflict. [#1739](https://github.com/dotnet/SqlClient/pull/1739)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.1.0-preview1.22278.1`. [#1787](https://github.com/dotnet/SqlClient/pull/1787) which includes TLS 1.3 Support and fix for AppDomain crash in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418)
+- Changed the `SqlConnectionEncryptOption` string parser to public. [#1771](https://github.com/dotnet/SqlClient/pull/1771)
+- Converted `ExecuteNonQueryAsync` to use async context object. [#1692](https://github.com/dotnet/SqlClient/pull/1692)
+- Code health improvements [#1604](https://github.com/dotnet/SqlClient/pull/1604) [#1598](https://github.com/dotnet/SqlClient/pull/1598) [#1595](https://github.com/dotnet/SqlClient/pull/1595) [#1443](https://github.com/dotnet/SqlClient/pull/1443)
+
+### Known issues
+
+- When using `Encrypt=Strict` with TLS v1.3, the TLS handshake occurs twice on initial connection on .NET Framework due to a timeout during the TLS handshake and a retry helper re-establishes the connection; however, on .NET Core, it will throw a `System.ComponentModel.Win32Exception (258): The wait operation timed out.` and is being investigated. If you're using Microsoft.Data.SqlClient with .NET Core on Windows 11, you will need to enable the managed SNI on Windows context switch using following statement `AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);` to use TLS v1.3 or disabling TLS 1.3 from the registry by assigning `0` to the following `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client\Enabled` registry key and it'll use TLS v1.2 for the connection. This will be fixed in a future release.
+
+## [Stable release 5.0.1] - 2022-10-07
+
+### Fixed
+
+- Fixed missing `HostNameInCertificate` connection string property in .NET Framework. [#1782](https://github.com/dotnet/SqlClient/pull/1782)
+- Fixed async deadlock issue when sending attention fails due to network failure. [#1783](https://github.com/dotnet/SqlClient/pull/1783)
+- Fixed **Null Reference Exception** on assigning `null` to `SqlConnectionStringBuilder.Encrypt`. [#1784](https://github.com/dotnet/SqlClient/pull/1784)
+- Fixed `ReadAsync()` behavior to register Cancellation token action before streaming results. [#1785](https://github.com/dotnet/SqlClient/pull/1785)
+- Fixed hang on infinite timeout and managed SNI. [#1798](https://github.com/dotnet/SqlClient/pull/1798)
+- Fixed Default UTF8 collation conflict. [#1799](https://github.com/dotnet/SqlClient/pull/1799)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.0.1` [#1795](https://github.com/dotnet/SqlClient/pull/1795), which includes the fix for AppDomain crash introducing in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418).
+
+## [Stable release 5.0.0] - 2022-08-05
+
+This update brings the below changes over the previous release:
+
+### Added
+
+- Added support for `TDS 8`. To use TDS 8, users should specify `Encrypt=Strict` in the connection string. [#1608](https://github.com/dotnet/SqlClient/pull/1608)
+- Added `TDS 8` version for TDSLogin. [#1657](https://github.com/dotnet/SqlClient/pull/1657)
+
+### Fixed
+
+- Fixed null SqlBinary as rowversion. [#1688](https://github.com/dotnet/SqlClient/pull/1688)
+- Fixed **KeyNotFoundException** for the `FailoverPartner` key on SQL servers with availability group configured. [#1614](https://github.com/dotnet/SqlClient/pull/1614)
+- Fixed small inconsistency between netcore and netfx for `EncryptionOptions`. [#1672](https://github.com/dotnet/SqlClient/pull/1672)
+- Fixed `Microsoft.SqlServer.Server` netcore project package reference. [#1654](https://github.com/dotnet/SqlClient/pull/1654)
+
+### Changed
+
+- Updated `AuthProviderInfo` struct to be matched the changes in native SNI for `TDS 8` server certificate validation. [#1680](https://github.com/dotnet/SqlClient/pull/1680)
+- Updated default system protocol for `TDS 8` on managed code. [#1678](https://github.com/dotnet/SqlClient/pull/1678)
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.0.0`. [#1680](https://github.com/dotnet/SqlClient/pull/1680)
+- Updated **IdentityModel** dependency from 6.8.0 to 6.21.0 and **IdentityClient** from 4.32.2 to 4.45.0. [#1646](https://github.com/dotnet/SqlClient/pull/1646)
+- Changed from union overlay design to reflected interfaces for SqlTypes. [1647](https://github.com/dotnet/SqlClient/pull/1647)
+
+## [Preview Release 5.0.0-preview3.22168.1] - 2022-06-16
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v5.0.0-preview2
+
+- Dropped classes from the `Microsoft.Data.SqlClient.Server` namespace and replaced them with supported types from the [Microsoft.SqlServer.Server](https://github.com/dotnet/SqlClient/tree/main/src/Microsoft.SqlServer.Server) package.[#1585](https://github.com/dotnet/SqlClient/pull/1585) The affected classes and enums are:
+ - Microsoft.Data.SqlClient.Server.IBinarySerialize -> Microsoft.SqlServer.Server.IBinarySerialize
+ - Microsoft.Data.SqlClient.Server.InvalidUdtException -> Microsoft.SqlServer.Server.InvalidUdtException
+ - Microsoft.Data.SqlClient.Server.SqlFacetAttribute -> Microsoft.SqlServer.Server.SqlFacetAttribute
+ - Microsoft.Data.SqlClient.Server.SqlFunctionAttribute -> Microsoft.SqlServer.Server.SqlFunctionAttribute
+ - Microsoft.Data.SqlClient.Server.SqlMethodAttribute -> Microsoft.SqlServer.Server.SqlMethodAttribute
+ - Microsoft.Data.SqlClient.Server.SqlUserDefinedAggregateAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
+ - Microsoft.Data.SqlClient.Server.SqlUserDefinedTypeAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
+ - (enum) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
+ - (enum) Microsoft.Data.SqlClient.Server.Format -> Microsoft.SqlServer.Server.Format
+ - (enum) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind
+
+### Added
+
+- Added support for `TDS 8`. To use TDS 8, users should specify Encrypt=Strict in the connection string. Strict mode disables TrustServerCertificate (always treated as False in Strict mode). HostNameInCertificate has been added to help some Strict mode scenarios. [#1608](https://github.com/dotnet/SqlClient/pull/1608)
+- Added support for specifying Server SPN and Failover Server SPN on the connection. [#1607](https://github.com/dotnet/SqlClient/pull/1607)
+- Added support for aliases when targeting .NET Core on Windows. [#1588](https://github.com/dotnet/SqlClient/pull/1588)
+
+### Fixed
+
+- Fixed naming, order, and formatting for `SqlDiagnosticsListener` on .NET Core and .NET. [#1637](https://github.com/dotnet/SqlClient/pull/1637)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1625](https://github.com/dotnet/SqlClient/pull/1625)
+- Added CommandText length validation when using stored procedure command types. [#1484](https://github.com/dotnet/SqlClient/pull/1484)
+- Fixed `GetSchema("StructuredTypeMembers")` to return correct schema information. [#1500](https://github.com/dotnet/SqlClient/pull/1500), [#1639](https://github.com/dotnet/SqlClient/pull/1639)
+- Fixed NullReferenceException when using `SqlDependency.Start` against an Azure SQL Database.[#1294](https://github.com/dotnet/SqlClient/pull/1294)
+- Send the correct retained transaction descriptor in the MARS TDS Header when there is no current transaction on .NET 5+ and .NET Core. [#1624](https://github.com/dotnet/SqlClient/pull/1624)
+- Parallelize SSRP requests (instance name resolution) on Linux and macOS when MultiSubNetFailover is specified. [#1578](https://github.com/dotnet/SqlClient/pull/1578)
+- Adjust the default ConnectRetryCount against Azure Synapse OnDemand endpoints [#1626](https://github.com/dotnet/SqlClient/pull/1626)
+
+### Changed
+
+- Code health improvements [#1353](https://github.com/dotnet/SqlClient/pull/1353) [#1354](https://github.com/dotnet/SqlClient/pull/1354) [#1525](https://github.com/dotnet/SqlClient/pull/1525) [#1186](https://github.com/dotnet/SqlClient/pull/1186)
+- Update Azure Identity dependency from 1.5.0 to 1.6.0.[#1611](https://github.com/dotnet/SqlClient/pull/1611)
+- Improved Regex for SqlCommandSet [#1548](https://github.com/dotnet/SqlClient/pull/1548)
+- Rework on `TdsParserStateObjectManaged` with nullable annotations. [#1555](https://github.com/dotnet/SqlClient/pull/1555)
+
+## [Preview Release 5.0.0-preview2.22096.2] - 2022-04-06
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v5.0.0-preview1
+
+- Dropped support for .NET Framework 4.6.1 [#1574](https://github.com/dotnet/SqlClient/pull/1574)
+
+### Fixed
+
+- Fixed connection failure by skipping Certificate Revocation List (CRL) check during authentication [#1559](https://github.com/dotnet/SqlClient/pull/1559)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.0.0-preview2.22084.1`. [#1563](https://github.com/dotnet/SqlClient/pull/1563)
+- Updated `Azure.Identity` version to `1.5.0` and `Microsoft.Identity.Client` version to `4.30.1` [#1462](https://github.com/dotnet/SqlClient/pull/1462)
+- Replaced AlwaysEncryptedAttestationException with SqlException [#1515](https://github.com/dotnet/SqlClient/pull/1515)
+- Improved error message when adding wrong type to SqlParameterCollection [#1547](https://github.com/dotnet/SqlClient/pull/1547)
+- Code health improvements [#1343](https://github.com/dotnet/SqlClient/pull/1343) [#1370](https://github.com/dotnet/SqlClient/pull/1370) [#1371](https://github.com/dotnet/SqlClient/pull/1371) [#1438](https://github.com/dotnet/SqlClient/pull/1438) [#1483](https://github.com/dotnet/SqlClient/pull/1483)
+
+## [Preview Release 5.0.0-preview1.22069.1] - 2022-03-09
+
+### Added
+
+- Added SqlDataSourceEnumerator. [#1430](https://github.com/dotnet/SqlClient/pull/1430)
+- Added new attestation protocol `None` option to forgo enclave attestation when using VBS enclaves. [#1425](https://github.com/dotnet/SqlClient/pull/1425) and [#1419](https://github.com/dotnet/SqlClient/pull/1419)
+- Added a new AppContext switch to suppress insecure TLS warnings. [#1457](https://github.com/dotnet/SqlClient/pull/1457)
+
+### Fixed
+
+- Fixed all documentation paths to Unix format path. [#1442](https://github.com/dotnet/SqlClient/pull/1442)
+- Fixed thread safety issue for `GetEnclaveProvider` by converting dictionary to concurrent dictionary. [#1451](https://github.com/dotnet/SqlClient/pull/1451)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v5.0.0-preview1.22062.1`. [#1537](https://github.com/dotnet/SqlClient/pull/1537)
+- Modernized style in ValueUtilSmi. [#1351](https://github.com/dotnet/SqlClient/pull/1351)
+- Changed SQL server codenames to version names. [#1439](https://github.com/dotnet/SqlClient/pull/1439)
+- Prevented subtype generation in project files. [#1452](https://github.com/dotnet/SqlClient/pull/1452)
+- Changed `Array.Copy` to `Buffer.BlockCopy` for byte arrays. [#1366](https://github.com/dotnet/SqlClient/pull/1366)
+- Changed files in csproj to be alphabetically sorted in netfx and netcore. [#1364](https://github.com/dotnet/SqlClient/pull/1364)
+- Sqlstream, SqlInternalTransaction and MetaDataUtilsSmi are moved to shared folder. [#1337](https://github.com/dotnet/SqlClient/pull/1337), [#1346](https://github.com/dotnet/SqlClient/pull/1346) and [#1339](https://github.com/dotnet/SqlClient/pull/1339)
+- Various code improvements: [#1197](https://github.com/dotnet/SqlClient/pull/1197), [#1313](https://github.com/dotnet/SqlClient/pull/1313),[#1330](https://github.com/dotnet/SqlClient/pull/1330),[#1366](https://github.com/dotnet/SqlClient/pull/1366), [#1435](https://github.com/dotnet/SqlClient/pull/1435),[#1478](https://github.com/dotnet/SqlClient/pull/1478)
+
+## [Stable release 4.1.1] - 2022-09-13
+
+### Fixed
+
+- Fixed connection failure by not requiring Certificate Revocation List (CRL) check during authentication. [#1706](https://github.com/dotnet/SqlClient/pull/1706)
+- Parallelize SSRP requests on Linux and macOS when MultiSubNetFailover is specified. [#1708](https://github.com/dotnet/SqlClient/pull/1708), [#1746](https://github.com/dotnet/SqlClient/pull/1746)
+- Added CommandText length validation when using stored procedure command types. [#1709](https://github.com/dotnet/SqlClient/pull/1709)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1710](https://github.com/dotnet/SqlClient/pull/1710)
+- Fixed null SqlBinary as rowversion. [#1712](https://github.com/dotnet/SqlClient/pull/1712)
+- Fixed table's collation overriding with default UTF8 collation. [#1749](https://github.com/dotnet/SqlClient/pull/1749)
+
+## Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.1` [#1755](https://github.com/dotnet/SqlClient/pull/1755), which includes the fix for AppDomain crash introducing in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418)
+- Various code improvements: [#1711](https://github.com/dotnet/SqlClient/pull/1711)
+
+## [Stable release 4.1.0] - 2022-01-31
+
+### Added
+
+- Added new Attestation Protocol `None` for `VBS` enclave types. This protocol will allow users to forgo enclave attestation for VBS enclaves. [#1419](https://github.com/dotnet/SqlClient/pull/1419) [#1425](https://github.com/dotnet/SqlClient/pull/1425)
+
+## [Stable release 4.0.2] - 2022-09-13
+
+### Fixed
+
+- Fixed connection failure by not requiring Certificate Revocation List (CRL) check during authentication. [#1718](https://github.com/dotnet/SqlClient/pull/1718)
+- Parallelize SSRP requests on Linux and macOS when MultiSubNetFailover is specified. [#1720](https://github.com/dotnet/SqlClient/pull/1720), [#1747](https://github.com/dotnet/SqlClient/pull/1747)
+- Added CommandText length validation when using stored procedure command types. [#1721](https://github.com/dotnet/SqlClient/pull/1721)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1722](https://github.com/dotnet/SqlClient/pull/1722)
+- Fixed null SqlBinary as rowversion. [#1724](https://github.com/dotnet/SqlClient/pull/1724)
+- Fixed table's collation overriding with default UTF8 collation. [#1750](https://github.com/dotnet/SqlClient/pull/1750)
+
+## Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.1` [#1754](https://github.com/dotnet/SqlClient/pull/1754), which includes the fix for AppDomain crash introducing in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418)
+- Various code improvements: [#1723](https://github.com/dotnet/SqlClient/pull/1723)
+
+## [Stable release 4.0.1] - 2022-01-17
+
+### Added
+
+Added AppContext switch `SuppressInsecureTLSWarning` to allow suppression of TLS security warning when using `Encrypt=false` in the connection string. [#1457](https://github.com/dotnet/SqlClient/pull/1457)
+
+### Fixed
+
+- Fixed Kerberos authentication failure when using .NET 6. [#1411](https://github.com/dotnet/SqlClient/pull/1411)
+- Fixed connection failure when using `SqlLocalDB` instance pipe name. [#1433](https://github.com/dotnet/SqlClient/pull/1433)
+- Fixed a failure when executing concurrent queries requiring enclaves. [#1451](https://github.com/dotnet/SqlClient/pull/1451)
+- Updated obsolete API calls targeting .NET 6. [#1401](https://github.com/dotnet/SqlClient/pull/1401)
+
+## [Stable Release 4.0.0] - 2021-11-18
+
+### Added
+
+- Added missing `SqlClientLogger` class to .NET Core refs and missing `SqlClientLogger.LogWarning` method in .NET Framework refs [#1392](https://github.com/dotnet/SqlClient/pull/1392)
+
+### Changed
+
+- Avoid throwing unnecessary exception when an invalid `SqlNotificationInfo` value is received from SQL Server [#1378](https://github.com/dotnet/SqlClient/pull/1378)
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.0` [#1391](https://github.com/dotnet/SqlClient/pull/1391)
+
+## [Preview Release 4.0.0-preview3.21293.2] - 2021-10-20
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v4.0.0-preview2
+
+- Dropped support for .NET Core 2.1 [#1272](https://github.com/dotnet/SqlClient/pull/1272)
+- [.NET Framework] Exception will not be thrown if a User ID is provided in the connection string when using `Active Directory Integrated` authentication [#1359](https://github.com/dotnet/SqlClient/pull/1359)
+
+### Added
+
+- Add `GetFieldValueAsync` and `GetFieldValue` support for `XmlReader`, `TextReader`, `Stream` [#1019](https://github.com/dotnet/SqlClient/pull/1019)
+
+### Fixed
+
+- Fixed `FormatException` when opening a connection with event tracing enabled [#1291](https://github.com/dotnet/SqlClient/pull/1291)
+- Fixed improper initialization of `ActiveDirectoryAuthenticationProvider` [#1328](https://github.com/dotnet/SqlClient/pull/1328)
+- Fixed `MissingMethodException` when accessing `SqlAuthenticationParameters.ConnectionTimeout` [#1336](https://github.com/dotnet/SqlClient/pull/1336)
+- Fixed data corruption issues by reverting changes to async cancellations [#1352](https://github.com/dotnet/SqlClient/pull/1352)
+- Fixed performance degradation by reverting changes to MARS state machine [#1357](https://github.com/dotnet/SqlClient/pull/1357)
+- Fixed bug where environment variables are ignored when using `Active Directory Default` authentication [#1360](https://github.com/dotnet/SqlClient/pull/1360)
+
+### Changed
+
+- Removed attributes for classes used in Microsoft.VSDesigner due to lack of support for Microsoft.Data.SqlClient [#1296](https://github.com/dotnet/SqlClient/pull/1296)
+- Disable encryption when connecting to SQL LocalDB [#1312](https://github.com/dotnet/SqlClient/pull/1312)
+- Various code health and performance improvements. See [milestone](https://github.com/dotnet/SqlClient/milestone/31?closed=1) for more info.
+
+## [Preview Release 4.0.0-preview2.21264.2] - 2021-09-21
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v4.0.0-preview1
+
+- Removed `Configurable Retry Logic` safety switch. [#1254](https://github.com/dotnet/SqlClient/pull/1254)
+
+### Added
+
+- Added support for `SqlFileStream` on Windows using .NET Standard 2.0 and above. [#1240](https://github.com/dotnet/SqlClient/pull/1240)
+- Added support for **localdb** `shared instance` using managed SNI. [#1237](https://github.com/dotnet/SqlClient/pull/1237)
+
+### Fixed
+
+- Fixed `.NET decimal` conversion from `SqlDecimal`. [#1179](https://github.com/dotnet/SqlClient/pull/1179)
+- Fixed `Event Source` changes on **TryBeginExecuteEvent** and **WriteEndExecuteEvent** to address the failure on other MS products such as OpenTelemetry and Application Insight. [#1258](https://github.com/dotnet/SqlClient/pull/1258)
+- Fixed command's async cancellation. [#956](https://github.com/dotnet/SqlClient/pull/956)
+- Fixed deadlock in transaction using .NET Framework. [#1242](https://github.com/dotnet/SqlClient/pull/1242)
+- Fixed unknown transaction state issues when prompting delegated transaction. [1216](https://github.com/dotnet/SqlClient/pull/1216)
+
+### Changed
+
+- Various code improvements [#1155](https://github.com/dotnet/SqlClient/pull/1155) [#1236](https://github.com/dotnet/SqlClient/pull/1236) [#1251](https://github.com/dotnet/SqlClient/pull/1251) [#1266](https://github.com/dotnet/SqlClient/pull/1266)
+
+## [Preview Release 4.0.0-preview1.21237.2] - 2021-08-25
+
+### Breaking changes over stable release 3.0.0
+
+- Changed `Encrypt` connection string property to be `true` by default. [#1210](https://github.com/dotnet/SqlClient/pull/1210)
+- The driver now throws `SqlException` replacing `AggregateException` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213)
+- Dropped obsolete `Asynchronous Processing` connection property from .NET Framework. [#1148](https://github.com/dotnet/SqlClient/pull/1148)
+
+### Added
+
+- Added `SqlCommand.EnableOptimizedParameterBinding` property that when enabled increases performance for commands with very large numbers of parameters. [#1041](https://github.com/dotnet/SqlClient/pull/1041)
+- Included `42108` and `42109` error codes to retriable transient errors list. [#1215](https://github.com/dotnet/SqlClient/pull/1215)
+- Added new App Context switch to use OS enabled client protocols only. [#1168](https://github.com/dotnet/SqlClient/pull/1168)
+- Added `PoolBlockingPeriod` connection property support in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181)
+- Added support for `SqlDataReader.GetColumnSchema()` in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181)
+- Added PropertyGrid support with component model annotations to `SqlConnectionStringBuilder` properties for .NET Core. [#1152](https://github.com/dotnet/SqlClient/pull/1152)
+
+### Fixed
+
+- Fixed issue with connectivity when TLS 1.3 is enabled on client and server. [#1168](https://github.com/dotnet/SqlClient/pull/1168)
+- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1210](https://github.com/dotnet/SqlClient/pull/1210)
+- Fixed issue where connection goes to unusable state. [#1128](https://github.com/dotnet/SqlClient/pull/1128)
+- Fixed recursive calls to `RetryLogicProvider` when calling `SqlCommand.ExecuteScalarAsync`. [#1220](https://github.com/dotnet/SqlClient/pull/1220)
+- Fixed async deadlock scenarios in web contexts with configurable retry logic provider. [#1220](https://github.com/dotnet/SqlClient/pull/1220)
+- Fixed `EntryPointNotFoundException` in `InOutOfProcHelper` constructor. [#1120](https://github.com/dotnet/SqlClient/pull/1120)
+- Fixed async thread blocking issues on `SqlConnection.Open()` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213)
+- Fixed driver behavior for Always Encrypted with secure enclaves to not fail when no user parameters have been provided. [#1115](https://github.com/dotnet/SqlClient/pull/1115)
+- Fixed bug with `LegacyRowVersionNullBehavior` App Context switch. [#1182](https://github.com/dotnet/SqlClient/pull/1182)
+- Fixed issues in Strings.resx file containing error messages. [#1136](https://github.com/dotnet/SqlClient/pull/1136) [#1178](https://github.com/dotnet/SqlClient/pull/1178)
+
+### Changed
+
+- Updated error code to match with Windows when certificate validation fails in non-Windows client environments. [#1130](https://github.com/dotnet/SqlClient/pull/1130)
+- Removed designer attributes from `SqlCommand` and `SqlDataAdapter`. [#1132](https://github.com/dotnet/SqlClient/pull/1132)
+- Updated configurable retry logic default retriable error list. [#1125](https://github.com/dotnet/SqlClient/pull/1125)
+- Improved performance by changing `SqlParameter` bool fields to flags. [#1064](https://github.com/dotnet/SqlClient/pull/1064)
+- Improved performance by implementing static delegates. [#1060](https://github.com/dotnet/SqlClient/pull/1060)
+- Optimized async method allocations in .NET Framework by porting changes from .NET Core. [#1084](https://github.com/dotnet/SqlClient/pull/1084)
+- Various code improvements [#902](https://github.com/dotnet/SqlClient/pull/902) [#925](https://github.com/dotnet/SqlClient/pull/925) [#933](https://github.com/dotnet/SqlClient/pull/933) [#934](https://github.com/dotnet/SqlClient/pull/934) [#1024](https://github.com/dotnet/SqlClient/pull/1024) [#1057](https://github.com/dotnet/SqlClient/pull/1057) [#1122](https://github.com/dotnet/SqlClient/pull/1122) [#1133](https://github.com/dotnet/SqlClient/pull/1133) [#1134](https://github.com/dotnet/SqlClient/pull/1134) [#1141](https://github.com/dotnet/SqlClient/pull/1141) [#1187](https://github.com/dotnet/SqlClient/pull/1187) [#1188](https://github.com/dotnet/SqlClient/pull/1188) [#1223](https://github.com/dotnet/SqlClient/pull/1223) [#1225](https://github.com/dotnet/SqlClient/pull/1225) [#1226](https://github.com/dotnet/SqlClient/pull/1226)
+
+## [Stable release 3.1.1] - 2022-08-12
+
+### Fixed
+
+- Fixed null SqlBinary as rowversion. [#1700](https://github.com/dotnet/SqlClient/pull/1700)
+- Fixed Kerberos authentication failure when using .NET 6. [#1696](https://github.com/dotnet/SqlClient/pull/1696)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1695](https://github.com/dotnet/SqlClient/pull/1695)
+- Removed union overlay design and use reflection in `SqlTypeWorkarounds`. [#1699](https://github.com/dotnet/SqlClient/pull/1699)
+
+## [Stable release 3.1.0] - 2022-03-30
+
+### Added
+
+- Added new Attestation Protocol `None` for `VBS` enclave types. This protocol will allow users to forgo enclave attestation for VBS enclaves. [#1539](https://github.com/dotnet/SqlClient/pull/1539)
+- Included `42108` and `42109` error codes to retriable transient errors list. [#1560](https://github.com/dotnet/SqlClient/pull/1560)
+
+### Fixed
+
+- Changed EnclaveDelegate.Crypto GetEnclaveProvider to use a thread safe concurrent dictionary. [#1564](https://github.com/dotnet/SqlClient/pull/1564
+
+## [Stable Release 3.0.1] - 2021-09-24
+
+### Fixed
+
+- Fixed async thread blocking issues on `SqlConnection.Open()` for active directory authentication modes. [#1270](https://github.com/dotnet/SqlClient/pull/1270)
+- Fixed unknown transaction state issues when prompting delegated transaction. [1247](https://github.com/dotnet/SqlClient/pull/1247)
+- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1233](https://github.com/dotnet/SqlClient/pull/1233)
+- Fixed bug with `LegacyRowVersionNullBehavior` App Context switch. [#1246](https://github.com/dotnet/SqlClient/pull/1246)
+- Fixed recursive calls to `RetryLogicProvider` when calling `SqlCommand.ExecuteScalarAsync`. [#1245](https://github.com/dotnet/SqlClient/pull/1245)
+- Fixed async deadlock scenarios in web contexts with configurable retry logic provider. [#1245](https://github.com/dotnet/SqlClient/pull/1245)
+- Fixed deadlock in transaction using .NET Framework. [#1243](https://github.com/dotnet/SqlClient/pull/1243)
+- Fixed issue where connection goes to unusable state. [#1238](https://github.com/dotnet/SqlClient/pull/1238)
+
+## [Stable Release 3.0.0] - 2021-06-09
+
+### Added
+
+- Added support for column encryption key caching when the server supports retrying queries that require enclave computations [#1062](https://github.com/dotnet/SqlClient/pull/1062)
+- Added support for configurable retry logic configuration file in .NET Standard [#1090](https://github.com/dotnet/SqlClient/pull/1090)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v3.0.0` [#1102](https://github.com/dotnet/SqlClient/pull/1102)
+- Improved event counter display information [#1091](https://github.com/dotnet/SqlClient/pull/1091)
+
+### Breaking Changes
+
+- Modified column encryption key store provider registrations to give built-in system providers precedence over providers registered on connection and command instances. [#1101](https://github.com/dotnet/SqlClient/pull/1101)
+
+## [Stable Release 2.1.5] - 2022-08-30
+
+### Fixed
+
+- Added CommandText length validation when using stored procedure command types. [#1726](https://github.com/dotnet/SqlClient/pull/1726)
+- Fixed Kerberos authentication failure when using .NET 6. [#1727](https://github.com/dotnet/SqlClient/pull/1727)
+- Removed union overlay design and use reflection in `SqlTypeWorkarounds`. [#1729](https://github.com/dotnet/SqlClient/pull/1729)
+
+## [Stable Release 2.1.4] - 2021-09-20
+
+### Fixed
+
+- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1232](https://github.com/dotnet/SqlClient/pull/1232)
+- Fixed issue where connection goes to unusable state. [#1239](https://github.com/dotnet/SqlClient/pull/1239)
+
+## [Stable Release 2.1.3] - 2021-05-21
+
+### Fixed
+
+- Fixed wrong data blended with transactions in .NET Core by marking a connection as doomed if the transaction completes or aborts while there is an open result set [#1051](https://github.com/dotnet/SqlClient/pull/1051)
+- Fixed race condition issues between SinglePhaseCommit and TransactionEnded events [#1049](https://github.com/dotnet/SqlClient/pull/1049)
+
+## [Preview Release 3.0.0-preview3.21140.5] - 2021-05-20
+
+### Added
+
+- Added support for "Active Directory Default" authentication mode [#1043](https://github.com/dotnet/SqlClient/pull/1043)
+- Added support for connection-level and command-level registration of custom key store providers to enable multi-tenant applications to control key store access [#1045](https://github.com/dotnet/SqlClient/pull/1045) [#1056](https://github.com/dotnet/SqlClient/pull/1056) [#1078](https://github.com/dotnet/SqlClient/pull/1078)
+- Added IP address preference support for TCP connections [#1015](https://github.com/dotnet/SqlClient/pull/1015)
+
+### Fixed
+
+- Fixed corrupted connection issue when an exception occurs during RPC execution with TVP types [#1068](https://github.com/dotnet/SqlClient/pull/1068)
+- Fixed race condition issues between SinglePhaseCommit and TransactionEnded events [#1042](https://github.com/dotnet/SqlClient/pull/1042)
+
+### Changed
+
+- Updated error messages for enclave exceptions to include a link to a troubleshooting guide. [#994](https://github.com/dotnet/SqlClient/pull/994)
+- Changes to share common files between projects [#1022](https://github.com/dotnet/SqlClient/pull/1022) [#1038](https://github.com/dotnet/SqlClient/pull/1038) [#1040](https://github.com/dotnet/SqlClient/pull/1040) [#1033](https://github.com/dotnet/SqlClient/pull/1033) [#1028](https://github.com/dotnet/SqlClient/pull/1028) [#1039](https://github.com/dotnet/SqlClient/pull/1039)
+
+## [Preview Release 3.0.0-preview2.21106.5] - 2021-04-16
+
+### Breaking Changes over preview release v3.0.0-preview1
+
+- `User Id` connection property now requires `Client Id` instead of `Object Id` for **User-Assigned Managed Identity** [#1010](https://github.com/dotnet/SqlClient/pull/1010)
+- `SqlDataReader` now returns a `DBNull` value instead of an empty `byte[]`. Legacy behavior can be enabled by setting `AppContext` switch **Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior** [#998](https://github.com/dotnet/SqlClient/pull/998)
+
+### Added
+
+- **Microsoft.Data.SqlClient** now depends on **Azure.Identity** library to acquire a token for "Active Directory Managed Identity/MSI" and "Active Directory Service Principal" authentication modes. [#1010](https://github.com/dotnet/SqlClient/pull/1010)
+- Upgraded Native SNI dependency to **v3.0.0-preview1** along with enhanced event tracing support [#1006](https://github.com/dotnet/SqlClient/pull/1006)
+
+### Fixed
+
+- Fixed wrong data blended with transactions in .NET Core by marking a connection as doomed if the transaction completes or aborts while there is an open result set[#1023](https://github.com/dotnet/SqlClient/pull/1023)
+- Fixed derived parameters containing incorrect TypeName [#1020](https://github.com/dotnet/SqlClient/pull/1020)
+- Fixed server connection leak possibilities when an exception occurs in pooling layer [#890](https://github.com/dotnet/SqlClient/pull/890)
+- Fixed IP connection resolving logic in .NET Core [#1016](https://github.com/dotnet/SqlClient/pull/1016) [#1031](https://github.com/dotnet/SqlClient/pull/1031)
+
+### Changed
+
+- Performance improvements in `SqlDateTime` to `DateTime` internal conversion method [#912](https://github.com/dotnet/SqlClient/pull/912)
+- Improved memory allocation by avoiding unnecessary context switching [1008](https://github.com/dotnet/SqlClient/pull/1008)
+- Updated `Microsoft.Identity.Client` version from **4.21.1** to **4.22.0** [#1036](https://github.com/dotnet/SqlClient/pull/1036)
+- Various performance improvements [#963](https://github.com/dotnet/SqlClient/pull/963) [#996](https://github.com/dotnet/SqlClient/pull/996) [#1004](https://github.com/dotnet/SqlClient/pull/1004) [#1012](https://github.com/dotnet/SqlClient/pull/1012) [#1017](https://github.com/dotnet/SqlClient/pull/1017)
+- Event source tracing improvements [#1018](https://github.com/dotnet/SqlClient/pull/1018)
+- Changes to share common files between NetFx and NetCore source code [#871](https://github.com/dotnet/SqlClient/pull/871) [#887](https://github.com/dotnet/SqlClient/pull/887)
+
+## [Preview Release 3.0.0-preview1.21075.2] - 2021-03-15
+
+### Breaking Changes over stable release v2.1
+
+- The minimum supported .NET Framework version has been increased to v4.6.1. .NET Framework v4.6.0 is no longer supported. [#899](https://github.com/dotnet/SqlClient/pull/899)
+
+### Added
+
+- Added support for Configurable Retry Logic [#693](https://github.com/dotnet/SqlClient/pull/693) [#966](https://github.com/dotnet/SqlClient/pull/966)
+- Added support for Event counters in .NET Core 3.1+ and .NET Standard 2.1+ [#719](https://github.com/dotnet/SqlClient/pull/719)
+- Added support for Assembly Context Unloading in .NET Core [#913](https://github.com/dotnet/SqlClient/pull/913)
+- Added missing `System.Runtime.Caching` dependency for .NET Standard assemblies [#877](https://github.com/dotnet/SqlClient/pull/877)
+
+### Fixed
+
+- Fixed wrong results issues by changing the timeout timer to ensure a correct execution state [#906](https://github.com/dotnet/SqlClient/pull/906)
+- Fixed Kerberos authentication issues when configured Server Principal Name (SPN) didn't contain default port [#930](https://github.com/dotnet/SqlClient/pull/930)
+- Fixed MARS header errors when `MakeReadAsyncBlocking` App Context switch is set to `false` [#910](https://github.com/dotnet/SqlClient/pull/910) [#922](https://github.com/dotnet/SqlClient/pull/922)
+- Fixed unwanted exceptions being thrown from `SqlDataReader.Dispose` [#920](https://github.com/dotnet/SqlClient/pull/920)
+- Fixed issues connecting to SQL Server instance with instance name specified from Unix environment [#870](https://github.com/dotnet/SqlClient/pull/870)
+- Fixed TCP Keep Alive issues in .NET Core [#854](https://github.com/dotnet/SqlClient/pull/854)
+- Fixed Kerberos Authentication issues caused due to regression [#845](https://github.com/dotnet/SqlClient/pull/845)
+- Fixed issues with System-Assigned Managed Identity in Azure Functions [#829](https://github.com/dotnet/SqlClient/pull/829)
+- Fixed missing error messages in Managed SNI [#882](https://github.com/dotnet/SqlClient/pull/882)
+- Fixed event source trace string issue [#940](https://github.com/dotnet/SqlClient/pull/940)
+
+### Changed
+
+- Changed App Context switch `MakeReadAsyncBlocking` default to `false` [#937](https://github.com/dotnet/SqlClient/pull/937)
+- Replaced usage of `BinaryFormatter` with `DataContractSerializer` [#869](https://github.com/dotnet/SqlClient/pull/869)
+- Prohibited `DtdProcessing` on `XmlTextReader` instance in .NET Core [#884](https://github.com/dotnet/SqlClient/pull/884)
+- Improved performance by reducing memory allocations in `SerializeEncodingChar`/`WriteEncodingChar` and some options boxing [#785](https://github.com/dotnet/SqlClient/pull/785)
+- Improved performance by preventing orphaned active packets being GC'ed without clear [#888](https://github.com/dotnet/SqlClient/pull/888)
+- Various performance improvements [#889](https://github.com/dotnet/SqlClient/pull/889) [#900](https://github.com/dotnet/SqlClient/pull/900)
+- Partial event source tracing improvements in .NET Core [#867](https://github.com/dotnet/SqlClient/pull/867) [#897](https://github.com/dotnet/SqlClient/pull/897)
+- Changes to share common files between NetFx and NetCore source code [#827](https://github.com/dotnet/SqlClient/pull/827) [#835](https://github.com/dotnet/SqlClient/pull/835) [#838](https://github.com/dotnet/SqlClient/pull/838) [#881](https://github.com/dotnet/SqlClient/pull/881)
+
+## [Stable Release 1.1.4] - 2021-03-10
+
+### Fixed
+
+- Fixed wrong results issues by changing the timeout timer to ensure a correct execution state [#950](https://github.com/dotnet/SqlClient/pull/950)
+- Fixed MARS header contains errors issue against .NET Framework 4.8+ [#959](https://github.com/dotnet/SqlClient/pull/959)
+
+## [Stable Release 2.1.2] - 2021-03-03
+
+### Fixed
+
+- Fixed issue connecting with instance name from a Linux/macOS environment [#874](https://github.com/dotnet/SqlClient/pull/874)
+- Fixed wrong results issues by changing the timeout timer to ensure a correct execution state [#929](https://github.com/dotnet/SqlClient/pull/929)
+- Fixed a vulnerability by prohibiting `DtdProcessing` on `XmlTextReader` instances in .NET Core [#885](https://github.com/dotnet/SqlClient/pull/885)
+- Fixed Kerberos authentication when an SPN does not contain the port [#935](https://github.com/dotnet/SqlClient/pull/935)
+- Fixed missing error messages in Managed SNI [#883](https://github.com/dotnet/SqlClient/pull/883)
+- Fixed missing `System.Runtime.Caching` dependency for .NET Standard assemblies [#878](https://github.com/dotnet/SqlClient/pull/878)
+- Fixed event source tracing issues [#941](https://github.com/dotnet/SqlClient/pull/941)
+- Fixed MARS header contains errors issue against .NET Framework 4.8.1 [#928](https://github.com/dotnet/SqlClient/pull/928)
+
+## [Stable Release 2.1.1] - 2020-12-18
+
+### Fixed
+
+- Fixed issue with System-Assigned Managed Identity in Azure Functions [#841](https://github.com/dotnet/SqlClient/pull/841)
+- Fixed issue with Kerberos Authentication for .NET Core in Unix environments [#848](https://github.com/dotnet/SqlClient/pull/848)
+- Fixed issue with TCP Keep Alive for .NET Core in Unix environments [#855](https://github.com/dotnet/SqlClient/pull/855)
+
## [Stable Release 2.1.0] - 2020-11-19
### Added
+
- Microsoft.Data.SqlClient symbols are now source-linked [#789](https://github.com/dotnet/SqlClient/pull/789)
- Added an API to clear cached access tokens from the token provider [#800](https://github.com/dotnet/SqlClient/pull/800)
- Added `SqlFacetAttribute` implementation [#757](https://github.com/dotnet/SqlClient/pull/757)
### Fixed
+
- Fixed `InvalidOperationException` and `NotSupportedException` errors due to `WriteAsync` collisions [#796](https://github.com/dotnet/SqlClient/pull/796)
- Fixed incorrect Settings.Async flag in `ExecuteXmlReaderAsync` [#782](https://github.com/dotnet/SqlClient/pull/782)
- Fixed a regression in Windows Integrated authentication when using managed networking [#777](https://github.com/dotnet/SqlClient/pull/777)
- Fixed Bulk Copy Async deadlock issues with custom `IDataReader` when using `SqlDataReader` internally [#779](https://github.com/dotnet/SqlClient/pull/779)
- Fixed a serialization issue with `SqlException` in .NET Core [#780](https://github.com/dotnet/SqlClient/pull/780)
-### Changes
-- Updated versions of `Microsoft.IdentityModel` package dependencies [#794](https://github.com/dotnet/SqlClient/pull/794)
+### Changed
+- Updated versions of `Microsoft.IdentityModel` package dependencies [#794](https://github.com/dotnet/SqlClient/pull/794)
## [Preview Release 2.1.0-preview2.20297.7] - 2020-10-23
### Added
+
- Added support for Azure Active Directory Managed Identity authentication [#730](https://github.com/dotnet/SqlClient/pull/730)
- Added support to provide a user-defined application client ID when using Active Directory authentication [#740](https://github.com/dotnet/SqlClient/pull/740)
- Added the "Command Timeout" connection string property to set a default timeout for all commands executed with the connection [#722](https://github.com/dotnet/SqlClient/pull/722)
- Added support for Always Encrypted on all supported platforms for .NET Standard 2.0 [#756](https://github.com/dotnet/SqlClient/pull/756)
### Fixed
+
- Fixed unobserved exception issue when a timeout occurs before a faulted task completes with an exception [#688](https://github.com/dotnet/SqlClient/pull/688) [#773](https://github.com/dotnet/SqlClient/pull/773)
- Fixed an issue where driver continues to prompt for credentials when using Azure Active Directory authentication [#770](https://github.com/dotnet/SqlClient/pull/770)
-### Changes
+### Changed
+
- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v2.1.1` and removed symbols from `Microsoft.Data.SqlClient.SNI.runtime`, which are now published to Microsoft Symbols Server [#764](https://github.com/dotnet/SqlClient/pull/764)
- Updated `Microsoft.Identity.Client` dependency version to `v4.21.1` [#765](https://github.com/dotnet/SqlClient/pull/765)
- Performance improvements when establishing an encrypted channel by removing sync over async method calls [#541](https://github.com/dotnet/SqlClient/pull/541)
- Performance improvements by replacing heap-allocated arrays with Spans [#667](https://github.com/dotnet/SqlClient/pull/667)
- Moved common files to shared folder between .NET Framework and .NET Core implementation [#734](https://github.com/dotnet/SqlClient/pull/734) [#753](https://github.com/dotnet/SqlClient/pull/753)
-
## [Stable Release 2.0.1] - 2020-08-25
### Added
+
- Added support for a new Configuration Section, `SqlClientAuthenticationProviders` (duplicate of existing `SqlAuthenticationProviders`), to allow co-existence of configurations for both drivers, "System.Data.SqlClient" and "Microsoft.Data.SqlClient" [#701](https://github.com/dotnet/SqlClient/pull/701)
### Fixed
+
- Fixed pooled connection re-use on access token expiry issue when using Active Directory authentication modes [#639](https://github.com/dotnet/SqlClient/pull/639)
- Fixed transient fault handling for Pooled connections [#638](https://github.com/dotnet/SqlClient/pull/638)
- Fixed Enclave session cache issue with Azure Database [#628](https://github.com/dotnet/SqlClient/pull/628)
@@ -55,10 +589,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Fixed configuration section collision issue with System.Data.SqlClient type [#701](https://github.com/dotnet/SqlClient/pull/701)
- Fixed blank error message [HTTP Provider] issues due to unexpected pre-login failures when using Native SNI. Fixed with Microsoft.Data.SqlClient.SNI v2.0.1 and Microsoft.Data.SqlClient.SNI.runtime v2.0.1 release versions.
-
## [Preview Release 2.1.0-preview1.20235.1] - 2020-08-21
### Added
+
- Added support for Always Encrypted with secure enclaves on Unix for .NET Core 2.1+ and on all supported platforms for .NET Standard 2.1+ [#676](https://github.com/dotnet/SqlClient/pull/676)
- Added support for Azure Active Directory Device Code Flow authentication [#597](https://github.com/dotnet/SqlClient/pull/597)
- Added Sensitivity Rank support in Sensitivity Classification information [#626](https://github.com/dotnet/SqlClient/pull/626)
@@ -68,13 +602,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Updated Microsoft.Data.SqlClient.SNI (.NET Framework dependency) and Microsoft.Data.SqlClient.SNI.runtime (.NET Core/Standard dependency) version to v2.1.0 with trace logging implementation [#705](https://github.com/dotnet/SqlClient/pull/705)
### Fixed
+
- Fixed Enclave session cache issue with Azure Database [#686](https://github.com/dotnet/SqlClient/pull/686)
- Fixed pooled connection re-use on access token expiry issue when using Active Directory authentication modes [#635](https://github.com/dotnet/SqlClient/pull/635)
- Fixed transient fault handling for Pooled connections [#637](https://github.com/dotnet/SqlClient/pull/637)
- Fixed SPN generation issue when no port is provided [#629](https://github.com/dotnet/SqlClient/pull/629)
- Fixed missing null checks for `SqlErrors` in `SqlException` for .NET Framework implementation [#698](https://github.com/dotnet/SqlClient/pull/698)
-### Changes
+### Changed
+
- Performance improvements by fixing unnecessary allocations with EventSource implementation [#684](https://github.com/dotnet/SqlClient/pull/684)
- Reverted changes to return empty DataTable from GetSchemaTable to return null as before. [#696](https://github.com/dotnet/SqlClient/pull/696)
- Removed multiple `CacheConnectionStringProperties` calls when setting `ConnectionString` properties [#683](https://github.com/dotnet/SqlClient/pull/683)
@@ -85,16 +621,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Performance improvements by moving `DataReader` caches to internal connection [#499](https://github.com/dotnet/SqlClient/pull/499)
- Moved common files to shared folder between .NET Framework and .NET Core implementation [#618](https://github.com/dotnet/SqlClient/pull/618) [#625](https://github.com/dotnet/SqlClient/pull/625)
-
## [Stable Release 2.0.0] - 2020-06-16
### Added
+
- Added internal driver support to provide resiliency to DNS failures [#594](https://github.com/dotnet/SqlClient/pull/594)
- Added support for `Active Directory Integrated`, `Active Directory Interactive` and `Active Directory Service Principal` authentication mode for .NET Core and .NET Standard [#560](https://github.com/dotnet/SqlClient/pull/560)
- Added support for `Active Directory Service Principal` authentication mode for .NET Framework [#560](https://github.com/dotnet/SqlClient/pull/560)
- Added support for optional `ORDER` hints in `SqlBulkCopy` for improved performance [#540](https://github.com/dotnet/SqlClient/pull/540)
### Fixed
+
- Fixed `SqlSequentialStream` multipacket read stalling issue in .NET Core [#603](https://github.com/dotnet/SqlClient/pull/603)
- Fixed code page issue for Kazakh collation in SQL Server [#584](https://github.com/dotnet/SqlClient/pull/584)
- Fixed stalled application issues when end of stream is reached [#577](https://github.com/dotnet/SqlClient/pull/577)
@@ -102,81 +639,91 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Fixed Object null reference issue when failover partner is set [#588](https://github.com/dotnet/SqlClient/pull/588)
- Fixed `applicationintent` connection string property issue [#585](https://github.com/dotnet/SqlClient/pull/585)
-### Changes
+### Changed
+
- Raise warning message when insecure TLS protocols are in use [#591](https://github.com/dotnet/SqlClient/pull/591)
### Breaking Changes
+
- Modified enclave provider interface `SqlColumnEncryptionEnclaveProvider` to be internal [#602](https://github.com/dotnet/SqlClient/pull/602) - _This change is not likely to impact customer applications since secure enclaves is a relatively new feature and they would have had to implement their own enclave provider, which is not a trivial task_.
- Updated `SqlClientMetaDataCollectionNames` exposed constants by removing non-existing constants and adding new to the metadata collection [#580](https://github.com/dotnet/SqlClient/pull/580)
-
## [Preview Release 2.0.0-preview4.20142.4] - 2020-05-21
### Added
+
- Microsoft.Data.SqlClient (.NET Core and .NET Standard) on Windows is now dependent on **Microsoft.Data.SqlClient.SNI.runtime**, replacing the previous dependency on **runtime.native.System.Data.SqlClient.SNI** [#570](https://github.com/dotnet/SqlClient/pull/570)
-- The new **Microsoft.Data.SqlClient.SNI.runtime** dependency adds support for the *ARM* platform along with the already supported platforms *ARM64*, *x64* and *x86* on Windows [#570](https://github.com/dotnet/SqlClient/pull/570)
+- The new **Microsoft.Data.SqlClient.SNI.runtime** dependency adds support for the _ARM_ platform along with the already supported platforms _ARM64_, _x64_ and _x86_ on Windows [#570](https://github.com/dotnet/SqlClient/pull/570)
- Improved driver performance by introducing managed packet recycling [#389](https://github.com/dotnet/SqlClient/pull/389)
### Fixed
+
- Fixed `SqlBulkCopy` to work with database columns containing metadata about data classification [#568](https://github.com/dotnet/SqlClient/pull/568)
- Fixed unsafe cast in `SqlException` for `SerializationEntry.Value`
- Fixed null reference exceptions in `SqlDelegatedTransaction` methods [#563](https://github.com/dotnet/SqlClient/pull/563)
-### Changes
+### Changed
+
- Standardized connection string properties for enhanced user experience [#534](https://github.com/dotnet/SqlClient/pull/534)
- Improved performance by reducing eventsource tracing related to allocations from TVP write methods [#557](https://github.com/dotnet/SqlClient/pull/557) [#564](https://github.com/dotnet/SqlClient/pull/564)
### Breaking Changes
-- For .NET Framework applications consuming **Microsoft.Data.SqlClient**, the `SNI.dll` files previously downloaded to the `bin\x64` and `bin\x86` folders are now named `Microsoft.Data.SqlClient.SNI.x64.dll` and `Microsoft.Data.SqlClient.SNI.x86.dll` and will be downloaded to the `bin` directory, to support auto-loading in the application process [#570](https://github.com/dotnet/SqlClient/pull/570). This change is not going to impact client applications unless a direct reference has been made to `SNI.dll` or the x86 and x64 folders.
+- For .NET Framework applications consuming **Microsoft.Data.SqlClient**, the `SNI.dll` files previously downloaded to the `bin\x64` and `bin\x86` folders are now named `Microsoft.Data.SqlClient.SNI.x64.dll` and `Microsoft.Data.SqlClient.SNI.x86.dll` and will be downloaded to the `bin` directory, to support auto-loading in the application process [#570](https://github.com/dotnet/SqlClient/pull/570). This change is not going to impact client applications unless a direct reference has been made to `SNI.dll` or the x86 and x64 folders.
## [Stable Release 1.1.3] - 2020-05-15
### Fixed
+
- Fixed driver behavior to not perform enlistment of pooled connection on aborted transaction [#551](https://github.com/dotnet/SqlClient/pull/551)
- Fixed issues introduced with MARS TDS Header fix in last release by reverting original change that caused issues. [#550](https://github.com/dotnet/SqlClient/pull/550)
-
## [Preview Release 2.0.0-preview3.20122.2] - 2020-05-01
### Added
+
- Allow passing username with Active Directory Interactive Authentication in .NET Framework [#492](https://github.com/dotnet/SqlClient/pull/492)
- Allow large UDT buffers for .NET Framework [#456](https://github.com/dotnet/SqlClient/pull/456)
- Added "Transaction Id" and "Client Version" in Diagnostic Source traces [#515](https://github.com/dotnet/SqlClient/pull/515)
- Added new `SqlConnectionOverrides` APIs to perform `SqlConnection.Open()` with fail fast option [#463](https://github.com/dotnet/SqlClient/pull/463)
### Fixed
+
- Addressed MARS TDS Header errors by reverting changes to make `SqlDataReader.ReadAsync()` non-blocking [#547](https://github.com/dotnet/SqlClient/pull/547)
- Fixed driver behavior to not perform enlistment of pooled connection in aborted transaction [#543](https://github.com/dotnet/SqlClient/pull/543)
- Fixed wrong application domain selected when starting `SqlDependencyListener` [#410](https://github.com/dotnet/SqlClient/pull/410)
- Added missing refs for `RowCopied` property in `SqlBulkCopy` [#508](https://github.com/dotnet/SqlClient/pull/508)
-### Changes
+### Changed
+
- Improved performance by removing unwanted method calls in Event Source tracing [#506](https://github.com/dotnet/SqlClient/pull/506)
- Removed Diagnostic Source and Configuration Manager dependencies from .NET Standard implementation [#535](https://github.com/dotnet/SqlClient/pull/535)
- Removed redundant calls to `DbConnectionPoolKey.GetType()` [#512](https://github.com/dotnet/SqlClient/pull/512)
### Breaking Changes
+
- Updated driver to perform decimal scale rounding to match SQL Server behavior [#470](https://github.com/dotnet/SqlClient/pull/470)
- Standardized App Context switch name that enables Managed SNI on Windows for .NET Core and .NET Standard (break only applies to 2.0 preview releases that introduced the switch) [#548](https://github.com/dotnet/SqlClient/pull/548)
-
## [Stable Release 1.1.2] - 2020-04-15
### Added
+
- Allowed passing username with Active Directory Interactive Authentication [#493](https://github.com/dotnet/SqlClient/pull/493) [#516](https://github.com/dotnet/SqlClient/pull/516)
### Fixed
+
- Fixed the ConnectionString's password persistence in .NET Core. [#489](https://github.com/dotnet/SqlClient/pull/489)
- Addressed MARS TDS header containing errors [#510](https://github.com/dotnet/SqlClient/pull/510)
### Changed
-- Updated driver libraries to be CLS Compliant [#522](https://github.com/dotnet/SqlClient/pull/522)
+- Updated driver libraries to be CLS Compliant [#522](https://github.com/dotnet/SqlClient/pull/522)
## [Preview Release 2.0.0-preview2.20084.1] - 2020-03-24
### Added
+
- Added support for capturing EventSource traces in .NET Framework, .NET Core, and .NET Standard applications [#399](https://github.com/dotnet/SqlClient/pull/399) [#461](https://github.com/dotnet/SqlClient/pull/461) [#479](https://github.com/dotnet/SqlClient/pull/479) [#483](https://github.com/dotnet/SqlClient/pull/483) [#484](https://github.com/dotnet/SqlClient/pull/484)
- Added support for Cross-platform TCP Keep Alive applicable to .NET Core 3.1+ applications [#395](https://github.com/dotnet/SqlClient/pull/395)
- Added support for enabling Managed networking implementation on Windows applicable to .NET Core and .NET Standard applications [#477](https://github.com/dotnet/SqlClient/pull/477)
@@ -186,11 +733,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Added cached `SqlReferenceCollection.FindLiveReaderContext` objects [#380](https://github.com/dotnet/SqlClient/pull/380)
### Fixed
+
- Fixed Access Token behavior in connection pool to perform string comparison [#443](https://github.com/dotnet/SqlClient/pull/443)
- Fixed concurrent connection speed issues when connecting with Azure Active Directory Authentication modes in .NET Core [#466](https://github.com/dotnet/SqlClient/pull/466)
- Fixed issues with `Password` persistence in Connection String [#453](https://github.com/dotnet/SqlClient/pull/453)
-### Changes
+### Changed
+
- Updated all driver assemblies to be CLS Compliant [#396](https://github.com/dotnet/SqlClient/pull/396)
- Updated Bulk Copy error messages to also include Column, Row and non-encrypted Data information [#437](https://github.com/dotnet/SqlClient/pull/437)
- Updated error messages for "Always Encrypted - Secure Enclaves" to handle 'Attestation Protocol' and fixed typos [#421](https://github.com/dotnet/SqlClient/pull/421) [#397](https://github.com/dotnet/SqlClient/pull/397)
@@ -199,25 +748,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Multiple performance improvements [#377](https://github.com/dotnet/SqlClient/pull/377) [#378](https://github.com/dotnet/SqlClient/pull/378) [#379](https://github.com/dotnet/SqlClient/pull/379)
### Breaking Changes
+
- The driver will now perform Server Certificate validation when TLS encryption is enforced by the target Server, which is the default for Azure connections [#391](https://github.com/dotnet/SqlClient/pull/391)
- `SqlDataReader.GetSchemaTable()` now returns an empty `DataTable` instead of returning `null` [#419](https://github.com/dotnet/SqlClient/pull/419)
-
## [Stable Release 1.1.1] - 2020-02-14
### Fixed
+
- Fixed deadlock issues by reverting async changes to `SNIPacket` [#425](https://github.com/dotnet/SqlClient/pull/425)
### Changed
-- Updated SNI package reference to include version range [#425](https://github.com/dotnet/SqlClient/pull/425)
+- Updated SNI package reference to include version range [#425](https://github.com/dotnet/SqlClient/pull/425)
## [Preview Release 2.0.0-preview1.20021.1] - 2020-01-21
### Added
+
- Added support to allow large UDT buffer size (_upto_ `Int.MaxValue`) as supported by SQL Server starting TDS 7.3 [#340](https://github.com/dotnet/SqlClient/pull/340)
### Fixed
+
- Fixed issues with `SqlCommandSet` not working with Byte Array parameters [#360](https://github.com/dotnet/SqlClient/pull/360)
- Fixed Statement command cancellation in Managed SNI [#248](https://github.com/dotnet/SqlClient/pull/248) - Ported [dotnet/corefx#38271](https://github.com/dotnet/corefx/pull/38271)
- Fixed zero connection timeout issue in Managed SNI [#332](https://github.com/dotnet/SqlClient/pull/332)
@@ -226,7 +778,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Fixed `ConnectionTime` and `ClientConnectionId` reported by `SqlStatistics` when connection is closed [#341](https://github.com/dotnet/SqlClient/pull/341)
- Fixed deadlock issues by reverting async changes to `SNIPacket` [#349](https://github.com/dotnet/SqlClient/pull/349)
-### Changes
+### Changed
+
- Improved performance of Managed SNI by removing double fetch of domain name [#366](https://github.com/dotnet/SqlClient/pull/366)
- Improved performance of Async Method Allocations in Managed SNI [#328](https://github.com/dotnet/SqlClient/pull/328)
- Improved performance of Managed SNI by enhancing utilization of resources [#173](https://github.com/dotnet/SqlClient/pull/173) - Ported [dotnet/corefx#35363](https://github.com/dotnet/corefx/pull/35363) and [dotnet/corefx#40732](https://github.com/dotnet/corefx/pull/40732)
@@ -235,31 +788,34 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Changed `Recieve()` and `ReceiveAsync()` implementation to receive null packets on failure [#350](https://github.com/dotnet/SqlClient/pull/350)
- Changed `EnclaveProviderBase` caching implementation to support Async Scenarios _(Introduces breaking changes)_ [#346](https://github.com/dotnet/SqlClient/pull/346)
-
## [Stable Release 1.1.0] - 2019-11-20
### Added
+
- Added support for |DataDirectory| macro in `AttachDBFilename` for .NET Core client [#284](https://github.com/dotnet/SqlClient/pull/284)
### Fixed
+
- Fixed connection resiliency check [#310](https://github.com/dotnet/SqlClient/pull/310)
- Fixed `SNIPacket.ReadFromStreamAsync` to not consume same `ValueTask` twice [#295](https://github.com/dotnet/SqlClient/pull/295)
- Fixed driver behavior to not send Attention signal for successful Bulk Copy operation [#308](https://github.com/dotnet/SqlClient/pull/308)
- Fixed driver behavior to abort connection when encountering `SqlException` on `SqlTransaction.Commit` [#299](https://github.com/dotnet/SqlClient/pull/299)
-- Fixed driver behavior to not throw exception on invalid *app.config* files [#319](https://github.com/dotnet/SqlClient/pull/319)
+- Fixed driver behavior to not throw exception on invalid _app.config_ files [#319](https://github.com/dotnet/SqlClient/pull/319)
+
+### Changed
-### Changes
- Improved async read performance by adding multi-packet target buffer caching [#285](https://github.com/dotnet/SqlClient/pull/285)
- Improved performance of `TdsParserStateObject` and `SqlDataReader` snapshot mechanisms [#198](https://github.com/dotnet/SqlClient/pull/198)
- Updated `SqlDataReader.Close` documentation [#314](https://github.com/dotnet/SqlClient/pull/314)
-
## [Preview Release 1.1.0-preview2.19309.1] - 2019-11-04
### Added
+
- Add support for secure enclaves with Always Encrypted [#293](https://github.com/dotnet/SqlClient/pull/293)
### Fixed
+
- Setting the value `DbParameter.DbType` to `DbType.Time` property fails after setting the Value property [#5](https://github.com/dotnet/SqlClient/issues/5)
- `SQLDataAdapter.FillSchema` doesn't mark computed columns as readonly [#275](https://github.com/dotnet/SqlClient/issues/275)
- `SqlDependency.Start` throws `FileNotFoundException` [#260](https://github.com/dotnet/SqlClient/issues/260)
@@ -270,7 +826,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Exception message grammar: "An SqlParameter [...] is not contained by this `SqlParameterCollection`" [#159](https://github.com/dotnet/SqlClient/issues/159)
- Fixing incorrect event id and opcode for the `SqlEventSource` [#241](https://github.com/dotnet/SqlClient/pull/241)
-### Changes
+### Changed
+
- Update dependency to Microsoft.Data.SqlClient.SNI v1.1.0 [#276](https://github.com/dotnet/SqlClient/pull/276)
- Correct timeout remarks for async command methods [#264](https://github.com/dotnet/SqlClient/pull/264)
- Improve `SqlBulkCopy` truncation error message [#256](https://github.com/dotnet/SqlClient/issues/256)
@@ -278,23 +835,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Enable SQL Command text for non-stored procs in EventSource events for .NET Framework [242](https://github.com/dotnet/SqlClient/pull/242)
- Many test changes to support a public CI
-
## [Preview Release 1.1.0-preview1.19275.1] - 2019-10-02
### Added
+
- Added `SqlFileStream` support for .NET Framework with `Microsoft.Data.SqlTypes.SqlFileStream` class introduced. [#210](https://github.com/dotnet/SqlClient/pull/210)
- Added support for Visual Studio Intellisense with XML Documentation. [#210](https://github.com/dotnet/SqlClient/pull/210)
-### Changes
+### Changed
+
- Synchronized ref definitions with driver classes. [#180](https://github.com/dotnet/SqlClient/pull/180)
- Updated `SNINativeMethodWrapper` to provide the underlying error in the inner exception when we fail to load SNI.dll. [#225](https://github.com/dotnet/SqlClient/pull/225)
- Added .editorconfig file and set formatting rules. [#193](https://github.com/dotnet/SqlClient/pull/193)
- Changes done to handle statistics well and to cleanup `AutoResetEvent` on disconnect. [#232](https://github.com/dotnet/SqlClient/pull/232)
-
## [Hotfix & Stable Release 1.0.19269.1] - 2019-09-26
### Fixed Issues
+
- `SqlCommand.StatementCompleted` event never being fired [#212](https://github.com/dotnet/SqlClient/issues/212)
- Added missing `Authentication` property to `SqlConnectionStringBuilder` reference assembly
- Reverted API changes in `SqlAuthenticationParameters` which had changed the `public string Resource` property to `public string[] Scopes`
@@ -302,6 +860,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [Hotfix & Stable Release 1.0.19249.1] - 2019-09-06
### Fixed Issues
+
- Fixed issues with large data reading in Unix applications when data is spanned over multiple packets. [#171](https://github.com/dotnet/SqlClient/pull/171)
## [Stable Release 1.0.19239.1] - 2019-08-27
diff --git a/README.md b/README.md
index 3c390cac58..29f8950a49 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
[](https://raw.githubusercontent.com/dotnet/sqlclient/master/LICENSE)
[](https://www.nuget.org/packages/Microsoft.Data.SqlClient)
[](https://gitter.im/Microsoft/mssql-developers)
+[](https://sqlclientdrivers.visualstudio.com/public/_build/latest?definitionId=1139)
# Microsoft SqlClient Data Provider for SQL Server
@@ -12,9 +13,9 @@ Microsoft.Data.SqlClient is a data provider for Microsoft SQL Server and Azure S
The Microsoft.Data.SqlClient package supports the below environments:
-- .NET Framework 4.6+
-- .NET Core 2.1+
-- .NET Standard 2.0+.
+- .NET Framework 4.6.2+
+- .NET Core 3.1+
+- .NET Standard 2.0+
The source code of this library is now available under the MIT license.
@@ -118,4 +119,4 @@ The Microsoft.Data.SqlClient Driver for SQL Server is licensed under the MIT lic
## Trademarks
-This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
\ No newline at end of file
+This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
diff --git a/RunPackageReferenceTests.cmd b/RunPackageReferenceTests.cmd
new file mode 100644
index 0000000000..fd37b9c7ba
--- /dev/null
+++ b/RunPackageReferenceTests.cmd
@@ -0,0 +1,146 @@
+@echo off
+
+:: .NET CORE + .NET STANDARD LIBRARY TEST CASES
+echo Building .NET Core Tests
+call :pauseOnError msbuild -t:Clean
+
+:: ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES ***************
+:: THESE ARE NOT STAND ALONE TEST COMMANDS AND NEED A DEVELOPER'S SPECIAL ATTENTION TO WORK. ATTEMPTING TO RUN THE ENTIRE SET OF COMMANDS AS-IS IS LIKELY TO FAIL!
+
+:: CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION
+:: > MSBuild -p:Configuration=Release
+
+:: Based on `dotnet test` documentation, the `Platform` property has no effect on choosing the underlying architecture for the test execution environment.
+:: You need to install and run the `dotnet` command for a specific architecture (x64, x86, Arm64).
+
+:: REFERENCE TYPE "PACKAGE"
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildAKVNetFx -p:ReferenceType=Package
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildAKVNetCore -p:ReferenceType=Package
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildAKVNetSt -p:ReferenceType=Package
+
+:: .NET - REFERENCE TYPE "PACKAGE"
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=Package -p:TargetNetCoreVersion=net6.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net6.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net6.0-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=Package -p:TargetNetCoreVersion=net7.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net7.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net7.0-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=Package -p:Platform=x64 -p:TargetNetCoreVersion=net6.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net6.0-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net6.0-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=Package -p:Platform=x64 -p:TargetNetCoreVersion=net7.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net7.0-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net7.0-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=Package -p:Platform=Win32 -p:TargetNetCoreVersion=net6.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net6.0-functional-win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net6.0-manual-win32.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=Package -p:Platform=Win32 -p:TargetNetCoreVersion=net7.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net7.0-functional-win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net7.0-manual-win32.xml
+
+:: .NET Framework - REFERENCE TYPE "PACKAGE"
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=Package -p:Platform=AnyCPU -p:TargetNetFxVersion=net462
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net462-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net462-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=Package -p:Platform=AnyCPU -p:TargetNetFxVersion=net48
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=Package -p:Platform=x64 -p:TargetNetFxVersion=net462
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net462-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net462-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:TargetNetFxVersion=net48 -p:Platform=x64 -p:ReferenceType=Package
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="x64" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=Package -p:Platform=Win32 -p:TargetNetFxVersion=net462
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net462-functional-win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net462-manual-win32.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:TargetNetFxVersion=net48 -p:Platform=Win32 -p:ReferenceType=Package
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-functional-Win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="Win32" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-manual-Win32.xml
+
+:: REFERENCE TYPE "NETSTANDARDPACKAGE"
+
+:: .NET - REFERENCE TYPE "NETSTANDARDPACKAGE"
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:TargetNetCoreVersion=net6.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:TargetNetCoreVersion=net7.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net7.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net7.0-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetCoreVersion=net6.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetCoreVersion=net7.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net7.0-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net7.0-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetCoreVersion=net6.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-functional-win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net6.0-manual-win32.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetCoreVersion=net7.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net7.0-functional-win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net7.0-manual-win32.xml
+
+:: .NET Framework - REFERENCE TYPE "NETSTANDARDPACKAGE"
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:TargetNetFxVersion=net462
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:TargetNetFxVersion=net48
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetFxVersion=net462
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=x64 -p:TargetNetFxVersion=net48
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-x64.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="x64" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-x64.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetFxVersion=net462
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-functional-win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net462 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net462-manual-win32.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:ReferenceType=NetStandardPackage -p:Platform=Win32 -p:TargetNetFxVersion=net48
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-win32.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -p:Platform="Win32" -p:TargetNetFxVersion=net48 -p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-win32.xml
+
+:: REFERENCE TYPE "NETSTANDARD" (We only build and test AnyCPU with Project Reference)
+:: NUGET PACKAGE GENERATION IS NOT SUPPORTED FOR REFERNCE TYPE 'NETSTANDARD'
+call :pauseOnError msbuild -p:Configuration="Release" -p:ReferenceType=NetStandard -p:GenerateNuget=false
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandard -p:TargetNetCoreVersion=net6.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net6.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net6.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net6.0-manual-anycpu.xml
+
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:ReferenceType=NetStandard -p:TargetNetCoreVersion=net7.0
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net7.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -p:Platform="AnyCPU" -p:TargetNetCoreVersion=net7.0 -p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-net7.0-manual-anycpu.xml
+
+:: TESTING 'NETSTANDARD' REFERENCE TYPE WITH .NET FRAMEWORK 4.6.2+ AS TARGET FRAMEWORK IS INVALID CASE AS PROJECT REFERENCE DOES NOT LOAD SNI.DLL IN .NET FRAMEWORK RUNTIME.
+:: CASE IS VERIFIED WITH RUNTIME.NATIVE.SYSTEM.DATA.SQLCLIENT.SNI AS WELL. TO TEST .NET FRAMEWORK TARGETS, USE 'NETSTANDARDPACKAGE' REFERENCE TYPE ONLY.
+
+goto :eof
+
+:pauseOnError
+%*
+if ERRORLEVEL 1 pause
+goto :eof
diff --git a/RunProjectReferenceTests.cmd b/RunProjectReferenceTests.cmd
new file mode 100644
index 0000000000..3b2208e82d
--- /dev/null
+++ b/RunProjectReferenceTests.cmd
@@ -0,0 +1,47 @@
+@echo off
+
+call :pauseOnError msbuild -t:Clean
+:: .NET FRAMEWORK - REFERENCE TYPE "PROJECT"
+:: Only Builds AnyCPU for project reference!
+
+:: Based on `dotnet test` documentation, the `Platform` property has no effect on choosing the underlying architecture for the test execution environment.
+:: You need to install and run the `dotnet` command for a specific architecture (x64, x86, Arm64).
+
+echo Building .NET Framework Tests ...
+call :pauseOnError msbuild -p:Configuration="Release"
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildAKVNetStAllOS
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildAKVNetFx
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:TargetNetFxVersion=net462
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetFx -p:TargetNetFxVersion=net48
+
+echo Running .NET Framework Tests ...
+call pause
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net462 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net462-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net462 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net462-manual-anycpu.xml
+
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj"-p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetfx" -p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-manual-anycpu.xml
+
+echo Building .NET Tests ...
+call pause
+call :pauseOnError msbuild -t:Clean
+call :pauseOnError msbuild -p:Configuration="Release"
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildAKVNetStAllOS
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildAKVNetCoreAllOS
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:TargetNetCoreVersion=net6.0
+call :pauseOnError msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:TargetNetCoreVersion=net7.0
+
+echo Running .NET Tests ...
+call pause
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" -p:TargetNetCoreVersion=net6.0 --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net6.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" -p:TargetNetCoreVersion=net6.0 --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net6.0-manual-anycpu.xml
+
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" -p:TargetNetCoreVersion=net7.0 --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net7.0-functional-anycpu.xml
+call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Configuration="Release" -p:TestTargetOS="Windowsnetcoreapp" -p:TargetNetCoreVersion=net7.0 --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net7.0-manual-anycpu.xml
+
+goto :eof
+
+:pauseOnError
+%*
+if ERRORLEVEL 1 pause
+goto :eof
diff --git a/RunTests.cmd b/RunTests.cmd
deleted file mode 100644
index 20dbd88287..0000000000
--- a/RunTests.cmd
+++ /dev/null
@@ -1,207 +0,0 @@
-@echo off
-
-:: .NET CORE + .NET STANDARD LIBRARY TEST CASES
-echo Building .NET Core Tests
-call :pauseOnError msbuild /t:Clean
-
-:: ************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES ***************
-:: CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION
-:: msbuild /p:configuration=Release
-
-:: REFERENCE TYPE "PACKAGE"
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildAKVNetFx /p:ReferenceType=Package
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildAKVNetCore /p:ReferenceType=Package
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore2.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore2.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore3.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore3.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore5.0-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore5.0-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:Platform=x64
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore2.1-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore2.1-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:Platform=x64 /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore3.1-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore3.1-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:Platform=x64 /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore5.0-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore5.0-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:Platform=Win32
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore2.1-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore2.1-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:Platform=Win32 /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore3.1-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore3.1-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=Package /p:Platform=Win32 /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore5.0-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-netcore5.0-manual-win32.xml
-
-:: REFERENCE TYPE "NETSTANDARDPACKAGE"
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore2.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore2.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore3.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore3.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore5.0-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore5.0-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:ReferenceType=NetStandardPackage /p:TargetNetFxVersion=net461
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetFxVersion=net461 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net461-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetFxVersion=net461 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net461-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:ReferenceType=NetStandardPackage /p:TargetNetFxVersion=net48
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetFxVersion=net48 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetFxVersion=net48 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:Platform=x64
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore2.1-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore2.1-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:Platform=x64 /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore3.1-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore3.1-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:Platform=x64 /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore5.0-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore5.0-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:ReferenceType=NetStandardPackage /p:Platform=x64 /p:TargetNetFxVersion=net461
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetFxVersion=net461 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net461-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetFxVersion=net461 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net461-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:ReferenceType=NetStandardPackage /p:Platform=x64 /p:TargetNetFxVersion=net48
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetFxVersion=net48 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="x64" /p:TargetNetFxVersion=net48 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:Platform=Win32
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore2.1-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore2.1-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:Platform=Win32 /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore3.1-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore3.1-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandardPackage /p:Platform=Win32 /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore5.0-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-netcore5.0-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:ReferenceType=NetStandardPackage /p:Platform=Win32 /p:TargetNetFxVersion=net461
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetFxVersion=net461 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net461-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetFxVersion=net461 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net461-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:ReferenceType=NetStandardPackage /p:Platform=Win32 /p:TargetNetFxVersion=net48
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetFxVersion=net48 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:Platform="Win32" /p:TargetNetFxVersion=net48 /p:ReferenceType=NetStandardPackage -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandardpackage-net48-manual-win32.xml
-
-:: REFERENCE TYPE "NETSTANDARD" (We only build and test AnyCPU with Project Reference)
-:: NUGET PACKAGE GENERATION IS NOT SUPPORTED FOR REFERNCE TYPE 'NETSTANDARD'
-call :pauseOnError msbuild /p:Configuration="Release" /p:ReferenceType=NetStandard /p:GenerateNuget=false
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandard
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-netcore2.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-netcore2.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandard /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-netcore3.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-netcore3.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:ReferenceType=NetStandard /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-netcore5.0-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=NetStandard -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\netstandard-netcore5.0-manual-anycpu.xml
-
-:: TESTING 'NETSTANDARD' REFERENCE TYPE WITH .NET FRAMEWORK 4.6.1+ AS TARGET FRAMEWORK IS INVALID CASE AS PROJECT REFERENCE DOES NOT LOAD SNI.DLL IN .NET FRAMEWORK RUNTIME.
-:: CASE IS VERIFIED WITH RUNTIME.NATIVE.SYSTEM.DATA.SQLCLIENT.SNI AS WELL. TO TEST .NET FRAMEWORK TARGETS, USE 'NETSTANDARDPACKAGE' REFERENCE TYPE ONLY.
-
-:: REFERENCE TYPE "PROJECT" (We only build and test AnyCPU with Project Reference)
-call :pauseOnError msbuild /p:Configuration="Release"
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildAKVNetFx
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildAKVNetCoreAllOS
-call :pauseOnError msbuild /p:Configuration="Release" /t:GenerateAKVProviderNugetPackage
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Project -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-netcore2.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp2.1 /p:ReferenceType=Project -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-netcore2.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:TargetNetCoreVersion=netcoreapp3.1
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Project -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-netcore3.1-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp3.1 /p:ReferenceType=Project -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-netcore3.1-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:TargetNetCoreVersion=netcoreapp5.0
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Project -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-netcore5.0-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" /p:Platform="AnyCPU" /p:TargetNetCoreVersion=netcoreapp5.0 /p:ReferenceType=Project -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-netcore5.0-manual-anycpu.xml
-
-:: .NET FRAMEWORK REFERENCE TYPE "PROJECT"
-echo Building .NET Framework Tests
-call :pauseOnError msbuild /p:Configuration="Release"
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildAKVNetFx
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildAKVNetCoreAllOS
-call :pauseOnError msbuild /p:Configuration="Release" /t:GenerateAKVProviderNugetPackage
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net46-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net46-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:TargetNetFxVersion=net48
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=x64
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net46-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net46-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=x64 /p:TargetNetFxVersion=net48
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=Win32
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net46-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net46-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=Win32 /p:TargetNetFxVersion=net48
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-functional-Win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\project-net48-manual-Win32.xml
-
-:: .NET FRAMEWORK REFERENCE TYPE "PACKAGE"
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:ReferenceType=Package
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net46-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net46-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:TargetNetFxVersion=net48 /p:ReferenceType=Package
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-functional-anycpu.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-manual-anycpu.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=x64 /p:ReferenceType=Package
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net46-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net46-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=x64 /p:TargetNetFxVersion=net48 /p:ReferenceType=Package
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-functional-x64.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="x64" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-manual-x64.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=Win32 /p:ReferenceType=Package
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net46-functional-win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net46-manual-win32.xml
-
-call :pauseOnError msbuild /p:Configuration="Release" /t:BuildTestsNetFx /p:Platform=Win32 /p:TargetNetFxVersion=net48 /p:ReferenceType=Package
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-functional-Win32.xml
-call :pauseOnError dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" /p:TargetNetFxVersion=net48 --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" /p:ReferenceType=Package -l:trx;LogFileName=..\..\..\..\..\artifacts\Results\package-net48-manual-Win32.xml
-
-goto :eof
-
-:pauseOnError
-%*
-if ERRORLEVEL 1 pause
-goto :eof
diff --git a/RunTests.sh b/RunTests.sh
index 1c4201371d..ed3f22a9a1 100644
--- a/RunTests.sh
+++ b/RunTests.sh
@@ -1,8 +1,8 @@
-dotnet msbuild /p:Configuration="Release" /t:Clean,BuildAll /p:GenerateDocumentationFile=false
+dotnet msbuild -p:Configuration="Release" -t:Clean,BuildAll -p:GenerateDocumentationFile=false
echo Building Add-Ons
-dotnet msbuild /p:Configuration="Release" /t:BuildAKVNetCore /p:OSGroup=Unix /p:Platform=AnyCPU
+dotnet msbuild -p:Configuration="Release" -t:BuildAKVNetCore -p:OSGroup=Unix -p:Platform=AnyCPU
echo Building tests
-dotnet msbuild /p:Configuration="Release" /t:BuildTestsNetCore /p:OSGroup=Unix /p:Platform=AnyCPU
+dotnet msbuild -p:Configuration="Release" -t:BuildTestsNetCore -p:OSGroup=Unix -p:Platform=AnyCPU
echo Running SqlClient test suite
-dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
-dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
+dotnet test "src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
+dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" -p:Platform="AnyCPU" -p:Configuration="Release" -p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests"
diff --git a/SUPPORT.md b/SUPPORT.md
index 861787eb5b..51a3996cca 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -4,7 +4,7 @@ Microsoft.Data.SqlClient library follows the latest .NET Core support policy for
[View the .NET Core Support Policy](https://dotnet.microsoft.com/platform/support/policy/dotnet-core)
-[View SqlClient Support Policy on Microsoft Documentation](https://docs.microsoft.com/sql/connect/ado-net/sqlclient-driver-support-lifecycle)
+View GA released version LTS/Current status and support dates here: [SqlClient Support Policy on Microsoft Documentation](https://docs.microsoft.com/sql/connect/ado-net/sqlclient-driver-support-lifecycle)
## Microsoft.Data.SqlClient release cadence
diff --git a/build.proj b/build.proj
index 2dcc4ae354..1b3372bc95 100644
--- a/build.proj
+++ b/build.proj
@@ -9,19 +9,42 @@
src\NuGet.configDebugAnyCPU
+
+ truetruefalseWindowsUnix
+ net6.0
+ netfx
+ netcore
+ netfx
+ netcoreapp
+ $(TF)
+ $(TF)true
+ Configuration=$(Configuration);AssemblyVersion=$(SqlServerAssemblyVersion);AssemblyFileVersion=$(SqlServerAssemblyFileVersion);Version=$(SqlServerPackageVersion);Configuration=$(Configuration);AssemblyFileVersion=$(AssemblyFileVersion);TargetsWindows=$(TargetsWindows);TargetsUnix=$(TargetsUnix);
- BuildProjectReferences=false;$(ProjectProperties);
- ContinuousIntegrationBuild=true
+ BuildProjectReferences=false;$(ProjectProperties);BuildForRelease=false;TargetNetCoreVersion=$(TargetNetCoreVersion);TargetNetFxVersion=$(TargetNetFxVersion)
+ TestResults
+
+
+
+
+
+
+ true
+ ContinuousIntegrationBuild=$(BuildForRelease);EmbedUntrackedSources=$(BuildForRelease)
+
@@ -33,7 +56,8 @@
-
+
+
@@ -43,38 +67,66 @@
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+ $(DotNetCmd) dotnet build -c Release -p:ReferenceType=$(ReferenceType)"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -86,23 +138,55 @@
-
+
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
@@ -113,18 +197,32 @@
-
+
-
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
@@ -132,4 +230,10 @@
+
+
+
+
+
+
diff --git a/buildAddons.cmd b/buildAddons.cmd
index e958ed14cb..e8d41ea3a8 100644
--- a/buildAddons.cmd
+++ b/buildAddons.cmd
@@ -1,8 +1,9 @@
-call :pauseOnError msbuild /p:configuration=Release /t:clean
-call :pauseOnError msbuild /p:configuration=Release /t:BuildAllConfigurations
-call :pauseOnError msbuild /p:configuration=Release /t:BuildAKVNetFx
-call :pauseOnError msbuild /p:configuration=Release /t:BuildAKVNetCoreAllOS
-call :pauseOnError msbuild /p:configuration=Release /t:GenerateAKVProviderNugetPackage
+call :pauseOnError msbuild -p:configuration=Release -t:clean
+call :pauseOnError msbuild -p:configuration=Release -t:BuildAllConfigurations
+call :pauseOnError msbuild -p:configuration=Release -t:BuildAKVNetFx
+call :pauseOnError msbuild -p:configuration=Release -t:BuildAKVNetCoreAllOS
+call :pauseOnError msbuild -p:configuration=Release -t:BuildAKVNetStAllOS
+call :pauseOnError msbuild -p:configuration=Release -t:GenerateAKVProviderNugetPackage
goto :eof
diff --git a/contributing-workflow.md b/contributing-workflow.md
index 374e843ae1..52ee5e5e15 100644
--- a/contributing-workflow.md
+++ b/contributing-workflow.md
@@ -6,7 +6,7 @@ You can contribute to Microsoft.Data.SqlClient with issues and PRs. Simply filin
We use and recommend the following workflow:
-1. Create an issue for your work.
+1. Create an issue for your work.
- You can skip this step for trivial changes.
- Reuse an existing issue on the topic, if there is one.
- Get agreement from the team and the community that your proposed change is a good one.
@@ -15,8 +15,8 @@ We use and recommend the following workflow:
- For any other improvements in the driver, add a Label "**Enhancement**" to your issue.
- Clearly state that you are going to take on implementing it, if that's the case. You can request that the issue be assigned to you. Note: The issue filer and the implementer don't have to be the same person.
2. Create a personal fork of the repository on GitHub (if you don't already have one).
-3. Create a branch off of master (`git checkout -b mybranch`).
- - Name the branch so that it clearly communicates your intentions, such as issue-123 or githubhandle-issue.
+3. Create a branch off of master (`git checkout -b mybranch`).
+ - Name the branch so that it clearly communicates your intentions, such as issue-123 or githubhandle-issue.
- Branches are useful since they isolate your changes from incoming changes from upstream. They also enable you to create multiple PRs from the same fork.
4. Make and commit your changes.
- Please follow our [Commit Messages](contributing.md#commit-messages) guidance.
@@ -41,7 +41,7 @@ If the CI build fails for any reason, the PR issue will be updated with a link t
## PR Feedback
-Microsoft team and community members will provide feedback on your change. Community feedback is highly valued. You will often see the absence of team feedback if the community has already provided good review feedback.
+Microsoft team and community members will provide feedback on your change. Community feedback is highly valued. You will often see the absence of team feedback if the community has already provided good review feedback.
1 or more Microsoft team members will review every PR prior to merge. They will often reply with "LGTM, modulo comments". That means that the PR will be merged once the feedback is resolved. "LGTM" == "looks good to me".
@@ -61,6 +61,16 @@ For testing PR changes and ensure they work fine, we maintain a public feed that
**Add this feed to NuGet Sources**
+```xml
+
+
+
+
+
+
+
+```
+OR
```cmd
nuget.exe sources Add -Name "Microsoft.Data.SqlClient.Commits" -Source "https://pkgs.dev.azure.com/sqlclientdrivers-ci/sqlclient/_packaging/Microsoft.Data.SqlClient.Commits/nuget/v3/index.json"
```
@@ -80,8 +90,26 @@ The package naming conventions follow SemVer 2.0.0 and also provide changeset in
Package names will be like: `Microsoft.Data.SqlClient.1.1.0-build.19250.1-c21aa7c.nupkg`
Breaking down:
-- `1.1.0-build` - Identitier for currently active driver version in Build.
+- `1.1.0-build` - Identifier for currently active driver version in Build.
- `19250.1` - Unique identifier to keep latest PRs on top of the feed.
- `c21aa7c` - Short Commit Id to identify merged commit in `master`.
> Note: This public feed is only for testing and validating new PR changes. Packages from feed will be eventually removed when the maximum NuGet Package limit of **50** is reached. We do not recommend using packages from this feed in client applications.
+
+## Nightly builds
+
+We also maintain NuGet feed for Nightly builds that are generated when new changes are merged in the repository. To access Nightly builds, add below configuration to package sources:
+
+```xml
+
+
+
+
+
+
+
+```
+OR
+```cmd
+nuget.exe sources Add -Name "Microsoft.Data.SqlClient.dev" -Source "https://pkgs.dev.azure.com/sqlclientdrivers-ci/sqlclient/_packaging/Microsoft.Data.SqlClient.dev/nuget/v3/index.json"
+```
diff --git a/doc/samples/AzureKeyVaultProviderExample.cs b/doc/samples/AzureKeyVaultProviderExample.cs
index 84c9ffb2da..e16a9a63a7 100644
--- a/doc/samples/AzureKeyVaultProviderExample.cs
+++ b/doc/samples/AzureKeyVaultProviderExample.cs
@@ -130,8 +130,8 @@ WITH VALUES (
private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
{
byte[] plainTextColumnEncryptionKey = new byte[32];
- RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
- rngCsp.GetBytes(plainTextColumnEncryptionKey);
+ RandomNumberGenerator rng = RandomNumberGenerator.Create();
+ rng.GetBytes(plainTextColumnEncryptionKey);
byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey);
string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
diff --git a/doc/samples/AzureKeyVaultProviderExample_2_0.cs b/doc/samples/AzureKeyVaultProviderExample_2_0.cs
new file mode 100644
index 0000000000..d4c64f9684
--- /dev/null
+++ b/doc/samples/AzureKeyVaultProviderExample_2_0.cs
@@ -0,0 +1,246 @@
+//
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using Azure.Identity;
+using Microsoft.Data.SqlClient;
+using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
+
+namespace Microsoft.Data.SqlClient.Samples
+{
+ public class AzureKeyVaultProviderExample_2_0
+ {
+ static readonly string s_algorithm = "RSA_OAEP";
+
+ // ********* Provide details here ***********
+ static readonly string s_akvUrl = "https://{KeyVaultName}.vault.azure.net/keys/{Key}/{KeyIdentifier}";
+ static readonly string s_connectionString = "Server={Server}; Database={database}; Integrated Security=true; Column Encryption Setting=Enabled;";
+ // ******************************************
+
+ public static void Main(string[] args)
+ {
+ // Initialize Token Credential instance using InteractiveBrowserCredential. For other authentication options,
+ // see classes derived from TokenCredential: https://docs.microsoft.com/dotnet/api/azure.core.tokencredential
+ InteractiveBrowserCredential interactiveBrowserCredential = new InteractiveBrowserCredential();
+
+ // Initialize AKV provider
+ SqlColumnEncryptionAzureKeyVaultProvider akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(interactiveBrowserCredential);
+
+ // Register AKV provider
+ SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders: new Dictionary(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
+ {
+ { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvProvider}
+ });
+ Console.WriteLine("AKV provider Registered");
+
+ // Create connection to database
+ using (SqlConnection sqlConnection = new SqlConnection(s_connectionString))
+ {
+ string cmkName = "CMK_WITH_AKV";
+ string cekName = "CEK_WITH_AKV";
+ string tblName = "AKV_TEST_TABLE";
+
+ CustomerRecord customer = new CustomerRecord(1, @"Microsoft", @"Corporation");
+
+ try
+ {
+ sqlConnection.Open();
+
+ // Drop Objects if exists
+ dropObjects(sqlConnection, cmkName, cekName, tblName);
+
+ // Create Column Master Key with AKV Url
+ createCMK(sqlConnection, cmkName);
+ Console.WriteLine("Column Master Key created.");
+
+ // Create Column Encryption Key
+ createCEK(sqlConnection, cmkName, cekName, akvProvider);
+ Console.WriteLine("Column Encryption Key created.");
+
+ // Create Table with Encrypted Columns
+ createTbl(sqlConnection, cekName, tblName);
+ Console.WriteLine("Table created with Encrypted columns.");
+
+ // Insert Customer Record in table
+ insertData(sqlConnection, tblName, customer);
+ Console.WriteLine("Encryted data inserted.");
+
+ // Read data from table
+ verifyData(sqlConnection, tblName, customer);
+ Console.WriteLine("Data validated successfully.");
+ }
+ finally
+ {
+ // Drop table and keys
+ dropObjects(sqlConnection, cmkName, cekName, tblName);
+ Console.WriteLine("Dropped Table, CEK and CMK");
+ }
+
+ Console.WriteLine("Completed AKV provider Sample.");
+ }
+ }
+
+ private static void createCMK(SqlConnection sqlConnection, string cmkName)
+ {
+ string KeyStoreProviderName = SqlColumnEncryptionAzureKeyVaultProvider.ProviderName;
+
+ string sql =
+ $@"CREATE COLUMN MASTER KEY [{cmkName}]
+ WITH (
+ KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
+ KEY_PATH = N'{s_akvUrl}'
+ );";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static void createCEK(SqlConnection sqlConnection, string cmkName, string cekName, SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
+ {
+ string sql =
+ $@"CREATE COLUMN ENCRYPTION KEY [{cekName}]
+ WITH VALUES (
+ COLUMN_MASTER_KEY = [{cmkName}],
+ ALGORITHM = '{s_algorithm}',
+ ENCRYPTED_VALUE = {GetEncryptedValue(sqlColumnEncryptionAzureKeyVaultProvider)}
+ )";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
+ {
+ byte[] plainTextColumnEncryptionKey = new byte[32];
+ RandomNumberGenerator rng = RandomNumberGenerator.Create();
+ rng.GetBytes(plainTextColumnEncryptionKey);
+
+ byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey);
+ string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
+ return EncryptedValue;
+ }
+
+ private static void createTbl(SqlConnection sqlConnection, string cekName, string tblName)
+ {
+ string ColumnEncryptionAlgorithmName = @"AEAD_AES_256_CBC_HMAC_SHA_256";
+
+ string sql =
+ $@"CREATE TABLE [dbo].[{tblName}]
+ (
+ [CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
+ [FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
+ [LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}')
+ )";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static void insertData(SqlConnection sqlConnection, string tblName, CustomerRecord customer)
+ {
+ string insertSql = $"INSERT INTO [{tblName}] (CustomerId, FirstName, LastName) VALUES (@CustomerId, @FirstName, @LastName);";
+
+ using (SqlTransaction sqlTransaction = sqlConnection.BeginTransaction())
+ using (SqlCommand sqlCommand = new SqlCommand(insertSql,
+ connection: sqlConnection, transaction: sqlTransaction,
+ columnEncryptionSetting: SqlCommandColumnEncryptionSetting.Enabled))
+ {
+ sqlCommand.Parameters.AddWithValue(@"CustomerId", customer.Id);
+ sqlCommand.Parameters.AddWithValue(@"FirstName", customer.FirstName);
+ sqlCommand.Parameters.AddWithValue(@"LastName", customer.LastName);
+
+ sqlCommand.ExecuteNonQuery();
+ sqlTransaction.Commit();
+ }
+ }
+
+ private static void verifyData(SqlConnection sqlConnection, string tblName, CustomerRecord customer)
+ {
+ // Test INPUT parameter on an encrypted parameter
+ using (SqlCommand sqlCommand = new SqlCommand($"SELECT CustomerId, FirstName, LastName FROM [{tblName}] WHERE FirstName = @firstName",
+ sqlConnection))
+ {
+ SqlParameter customerFirstParam = sqlCommand.Parameters.AddWithValue(@"firstName", @"Microsoft");
+ customerFirstParam.Direction = System.Data.ParameterDirection.Input;
+ customerFirstParam.ForceColumnEncryption = true;
+
+ using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
+ {
+ ValidateResultSet(sqlDataReader);
+ }
+ }
+ }
+
+ private static void ValidateResultSet(SqlDataReader sqlDataReader)
+ {
+ Console.WriteLine(" * Row available: " + sqlDataReader.HasRows);
+
+ while (sqlDataReader.Read())
+ {
+ if (sqlDataReader.GetInt32(0) == 1)
+ {
+ Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
+ }
+ else
+ {
+ Console.WriteLine("Employee Id didn't match");
+ }
+
+ if (sqlDataReader.GetString(1) == @"Microsoft")
+ {
+ Console.WriteLine(" * Employee Firstname received as sent: " + sqlDataReader.GetString(1));
+ }
+ else
+ {
+ Console.WriteLine("Employee FirstName didn't match.");
+ }
+
+ if (sqlDataReader.GetString(2) == @"Corporation")
+ {
+ Console.WriteLine(" * Employee LastName received as sent: " + sqlDataReader.GetString(2));
+ }
+ else
+ {
+ Console.WriteLine("Employee LastName didn't match.");
+ }
+ }
+ }
+
+ private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string tblName)
+ {
+ using (SqlCommand cmd = sqlConnection.CreateCommand())
+ {
+ cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN DROP TABLE [{tblName}] END";
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name = '{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name = '{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
+ cmd.ExecuteNonQuery();
+ }
+ }
+
+ private class CustomerRecord
+ {
+ internal int Id { get; set; }
+ internal string FirstName { get; set; }
+ internal string LastName { get; set; }
+
+ public CustomerRecord(int id, string fName, string lName)
+ {
+ Id = id;
+ FirstName = fName;
+ LastName = lName;
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs b/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs
new file mode 100644
index 0000000000..d691455f06
--- /dev/null
+++ b/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs
@@ -0,0 +1,368 @@
+//
+using System;
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using Azure.Identity;
+using Microsoft.Data.SqlClient;
+using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
+
+namespace Microsoft.Data.SqlClient.Samples
+{
+ public class AzureKeyVaultProviderLegacyExample_2_0
+ {
+ const string s_algorithm = "RSA_OAEP";
+
+ // ********* Provide details here ***********
+ static readonly string s_akvUrl = "https://{KeyVaultName}.vault.azure.net/keys/{Key}/{KeyIdentifier}";
+ static readonly string s_clientId = "{Application_Client_ID}";
+ static readonly string s_clientSecret = "{Application_Client_Secret}";
+ static readonly string s_connectionString = "Server={Server}; Database={database}; Integrated Security=true; Column Encryption Setting=Enabled;";
+ // ******************************************
+
+ public static void Main()
+ {
+ // Initialize AKV provider
+ SqlColumnEncryptionAzureKeyVaultProvider akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(new LegacyAuthCallbackTokenCredential());
+
+ // Register AKV provider
+ SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders: new Dictionary(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
+ {
+ { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvProvider}
+ });
+ Console.WriteLine("AKV provider Registered");
+
+ // Create connection to database
+ using (SqlConnection sqlConnection = new SqlConnection(s_connectionString))
+ {
+ string cmkName = "CMK_WITH_AKV";
+ string cekName = "CEK_WITH_AKV";
+ string tblName = "AKV_TEST_TABLE";
+
+ CustomerRecord customer = new CustomerRecord(1, @"Microsoft", @"Corporation");
+
+ try
+ {
+ sqlConnection.Open();
+
+ // Drop Objects if exists
+ dropObjects(sqlConnection, cmkName, cekName, tblName);
+
+ // Create Column Master Key with AKV Url
+ createCMK(sqlConnection, cmkName);
+ Console.WriteLine("Column Master Key created.");
+
+ // Create Column Encryption Key
+ createCEK(sqlConnection, cmkName, cekName, akvProvider);
+ Console.WriteLine("Column Encryption Key created.");
+
+ // Create Table with Encrypted Columns
+ createTbl(sqlConnection, cekName, tblName);
+ Console.WriteLine("Table created with Encrypted columns.");
+
+ // Insert Customer Record in table
+ insertData(sqlConnection, tblName, customer);
+ Console.WriteLine("Encryted data inserted.");
+
+ // Read data from table
+ verifyData(sqlConnection, tblName, customer);
+ Console.WriteLine("Data validated successfully.");
+ }
+ finally
+ {
+ // Drop table and keys
+ dropObjects(sqlConnection, cmkName, cekName, tblName);
+ Console.WriteLine("Dropped Table, CEK and CMK");
+ }
+
+ Console.WriteLine("Completed AKV provider Sample.");
+ }
+ }
+
+ private static void createCMK(SqlConnection sqlConnection, string cmkName)
+ {
+ string KeyStoreProviderName = SqlColumnEncryptionAzureKeyVaultProvider.ProviderName;
+
+ string sql =
+ $@"CREATE COLUMN MASTER KEY [{cmkName}]
+ WITH (
+ KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
+ KEY_PATH = N'{s_akvUrl}'
+ );";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static void createCEK(SqlConnection sqlConnection, string cmkName, string cekName, SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
+ {
+ string sql =
+ $@"CREATE COLUMN ENCRYPTION KEY [{cekName}]
+ WITH VALUES (
+ COLUMN_MASTER_KEY = [{cmkName}],
+ ALGORITHM = '{s_algorithm}',
+ ENCRYPTED_VALUE = {GetEncryptedValue(sqlColumnEncryptionAzureKeyVaultProvider)}
+ )";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
+ {
+ byte[] plainTextColumnEncryptionKey = new byte[32];
+ RandomNumberGenerator rng = RandomNumberGenerator.Create();
+ rng.GetBytes(plainTextColumnEncryptionKey);
+
+ byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey);
+ string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
+ return EncryptedValue;
+ }
+
+ private static void createTbl(SqlConnection sqlConnection, string cekName, string tblName)
+ {
+ string ColumnEncryptionAlgorithmName = @"AEAD_AES_256_CBC_HMAC_SHA_256";
+
+ string sql =
+ $@"CREATE TABLE [dbo].[{tblName}]
+ (
+ [CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
+ [FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
+ [LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = '{ColumnEncryptionAlgorithmName}')
+ )";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static void insertData(SqlConnection sqlConnection, string tblName, CustomerRecord customer)
+ {
+ string insertSql = $"INSERT INTO [{tblName}] (CustomerId, FirstName, LastName) VALUES (@CustomerId, @FirstName, @LastName);";
+
+ using (SqlTransaction sqlTransaction = sqlConnection.BeginTransaction())
+ using (SqlCommand sqlCommand = new SqlCommand(insertSql,
+ connection: sqlConnection, transaction: sqlTransaction,
+ columnEncryptionSetting: SqlCommandColumnEncryptionSetting.Enabled))
+ {
+ sqlCommand.Parameters.AddWithValue(@"CustomerId", customer.Id);
+ sqlCommand.Parameters.AddWithValue(@"FirstName", customer.FirstName);
+ sqlCommand.Parameters.AddWithValue(@"LastName", customer.LastName);
+
+ sqlCommand.ExecuteNonQuery();
+ sqlTransaction.Commit();
+ }
+ }
+
+ private static void verifyData(SqlConnection sqlConnection, string tblName, CustomerRecord customer)
+ {
+ // Test INPUT parameter on an encrypted parameter
+ using (SqlCommand sqlCommand = new SqlCommand($"SELECT CustomerId, FirstName, LastName FROM [{tblName}] WHERE FirstName = @firstName",
+ sqlConnection))
+ {
+ SqlParameter customerFirstParam = sqlCommand.Parameters.AddWithValue(@"firstName", @"Microsoft");
+ customerFirstParam.Direction = System.Data.ParameterDirection.Input;
+ customerFirstParam.ForceColumnEncryption = true;
+
+ using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
+ {
+ ValidateResultSet(sqlDataReader);
+ }
+ }
+ }
+
+ private static void ValidateResultSet(SqlDataReader sqlDataReader)
+ {
+ Console.WriteLine(" * Row available: " + sqlDataReader.HasRows);
+
+ while (sqlDataReader.Read())
+ {
+ if (sqlDataReader.GetInt32(0) == 1)
+ {
+ Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
+ }
+ else
+ {
+ Console.WriteLine("Employee Id didn't match");
+ }
+
+ if (sqlDataReader.GetString(1) == @"Microsoft")
+ {
+ Console.WriteLine(" * Employee Firstname received as sent: " + sqlDataReader.GetString(1));
+ }
+ else
+ {
+ Console.WriteLine("Employee FirstName didn't match.");
+ }
+
+ if (sqlDataReader.GetString(2) == @"Corporation")
+ {
+ Console.WriteLine(" * Employee LastName received as sent: " + sqlDataReader.GetString(2));
+ }
+ else
+ {
+ Console.WriteLine("Employee LastName didn't match.");
+ }
+ }
+ }
+
+ private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string tblName)
+ {
+ using (SqlCommand cmd = sqlConnection.CreateCommand())
+ {
+ cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN DROP TABLE [{tblName}] END";
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name = '{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name = '{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
+ cmd.ExecuteNonQuery();
+ }
+ }
+
+ private class CustomerRecord
+ {
+ internal int Id { get; set; }
+ internal string FirstName { get; set; }
+ internal string LastName { get; set; }
+
+ public CustomerRecord(int id, string fName, string lName)
+ {
+ Id = id;
+ FirstName = fName;
+ LastName = lName;
+ }
+ }
+
+ private class LegacyAuthCallbackTokenCredential : TokenCredential
+ {
+ string _authority = "";
+ string _resource = "";
+ string _akvUrl = "";
+
+ public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) =>
+ AcquireTokenAsync().GetAwaiter().GetResult();
+
+ public override async ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) =>
+ await AcquireTokenAsync();
+
+ private async Task AcquireTokenAsync()
+ {
+ // Added to reduce HttpClient calls.
+ // For multi-user support, a better design can be implemented as needed.
+ if (_akvUrl != s_akvUrl)
+ {
+ using (HttpClient httpClient = new HttpClient())
+ {
+ HttpResponseMessage response = await httpClient.GetAsync(s_akvUrl);
+ string challenge = response?.Headers.WwwAuthenticate.FirstOrDefault()?.ToString();
+ string trimmedChallenge = ValidateChallenge(challenge);
+ string[] pairs = trimmedChallenge.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
+
+ if (pairs != null && pairs.Length > 0)
+ {
+ for (int i = 0; i < pairs.Length; i++)
+ {
+ string[] pair = pairs[i]?.Split('=');
+
+ if (pair.Length == 2)
+ {
+ string key = pair[0]?.Trim().Trim(new char[] { '\"' });
+ string value = pair[1]?.Trim().Trim(new char[] { '\"' });
+
+ if (!string.IsNullOrEmpty(key))
+ {
+ if (key.Equals("authorization", StringComparison.InvariantCultureIgnoreCase))
+ {
+ _authority = value;
+ }
+ else if (key.Equals("resource", StringComparison.InvariantCultureIgnoreCase))
+ {
+ _resource = value;
+ }
+ }
+ }
+ }
+ }
+ }
+ _akvUrl = s_akvUrl;
+ }
+
+ string strAccessToken = await AzureActiveDirectoryAuthenticationCallback(_authority, _resource);
+ DateTime expiryTime = InterceptAccessTokenForExpiry(strAccessToken);
+ return new AccessToken(strAccessToken, new DateTimeOffset(expiryTime));
+ }
+
+ private DateTime InterceptAccessTokenForExpiry(string accessToken)
+ {
+ if (null == accessToken)
+ {
+ throw new ArgumentNullException(accessToken);
+ }
+
+ var jwtHandler = new JwtSecurityTokenHandler();
+ var jwtOutput = string.Empty;
+
+ // Check Token Format
+ if (!jwtHandler.CanReadToken(accessToken))
+ throw new FormatException(accessToken);
+
+ JwtSecurityToken token = jwtHandler.ReadJwtToken(accessToken);
+
+ // Re-serialize the Token Headers to just Key and Values
+ var jwtHeader = JsonConvert.SerializeObject(token.Header.Select(h => new { h.Key, h.Value }));
+ jwtOutput = $"{{\r\n\"Header\":\r\n{JToken.Parse(jwtHeader)},";
+
+ // Re-serialize the Token Claims to just Type and Values
+ var jwtPayload = JsonConvert.SerializeObject(token.Claims.Select(c => new { c.Type, c.Value }));
+ jwtOutput += $"\r\n\"Payload\":\r\n{JToken.Parse(jwtPayload)}\r\n}}";
+
+ // Output the whole thing to pretty JSON object formatted.
+ string jToken = JToken.Parse(jwtOutput).ToString(Formatting.Indented);
+ JToken payload = JObject.Parse(jToken).GetValue("Payload");
+
+ return new DateTime(1970, 1, 1).AddSeconds((long)payload[4]["Value"]);
+ }
+
+ private static string ValidateChallenge(string challenge)
+ {
+ string Bearer = "Bearer ";
+ if (string.IsNullOrEmpty(challenge))
+ throw new ArgumentNullException(nameof(challenge));
+
+ string trimmedChallenge = challenge.Trim();
+
+ if (!trimmedChallenge.StartsWith(Bearer))
+ throw new ArgumentException("Challenge is not Bearer", nameof(challenge));
+
+ return trimmedChallenge.Substring(Bearer.Length);
+ }
+
+ ///
+ /// Legacy implementation of Authentication Callback, used by Azure Key Vault provider 1.0.
+ /// This can be leveraged to support multi-user authentication support in the same Azure Key Vault Provider.
+ ///
+ /// Authorization URL
+ /// Resource
+ ///
+ public static async Task AzureActiveDirectoryAuthenticationCallback(string authority, string resource)
+ {
+ var authContext = new AuthenticationContext(authority);
+ ClientCredential clientCred = new ClientCredential(s_clientId, s_clientSecret);
+ AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred);
+ if (result == null)
+ {
+ throw new InvalidOperationException($"Failed to retrieve an access token for {resource}");
+ }
+ return result.AccessToken;
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs
index 628a2e663b..2091dab322 100644
--- a/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs
+++ b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample.cs
@@ -136,8 +136,8 @@ WITH VALUES (
private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
{
byte[] plainTextColumnEncryptionKey = new byte[32];
- RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
- rngCsp.GetBytes(plainTextColumnEncryptionKey);
+ RandomNumberGenerator rng = RandomNumberGenerator.Create();
+ rng.GetBytes(plainTextColumnEncryptionKey);
byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey);
string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
diff --git a/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs
new file mode 100644
index 0000000000..27f97dac38
--- /dev/null
+++ b/doc/samples/AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs
@@ -0,0 +1,250 @@
+using System;
+//
+using System.Collections.Generic;
+using System.Security.Cryptography;
+using System.Threading.Tasks;
+using Azure.Identity;
+using Microsoft.Data.SqlClient;
+using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
+
+namespace AKVEnclaveExample
+{
+ class Program
+ {
+ static readonly string s_algorithm = "RSA_OAEP";
+
+ // ********* Provide details here ***********
+ static readonly string s_akvUrl = "https://{KeyVaultName}.vault.azure.net/keys/{Key}/{KeyIdentifier}";
+ static readonly string s_connectionString = "Server={Server}; Database={database}; Integrated Security=true; Column Encryption Setting=Enabled; Attestation Protocol=HGS; Enclave Attestation Url = {attestation_url_for_HGS};";
+ // ******************************************
+
+ static void Main(string[] args)
+ {
+ // Initialize Token Credential instance using InteractiveBrowserCredential. For other authentication options,
+ // see classes derived from TokenCredential: https://docs.microsoft.com/dotnet/api/azure.core.tokencredential
+ InteractiveBrowserCredential interactiveBrowserCredential = new InteractiveBrowserCredential();
+
+ // Initialize AKV provider
+ SqlColumnEncryptionAzureKeyVaultProvider akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(interactiveBrowserCredential);
+
+ // Register AKV provider
+ SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customProviders: new Dictionary(capacity: 1, comparer: StringComparer.OrdinalIgnoreCase)
+ {
+ { SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvProvider}
+ });
+ Console.WriteLine("AKV provider Registered");
+
+ // Create connection to database
+ using (SqlConnection sqlConnection = new SqlConnection(s_connectionString))
+ {
+ string cmkName = "CMK_WITH_AKV";
+ string cekName = "CEK_WITH_AKV";
+ string tblName = "AKV_TEST_TABLE";
+
+ CustomerRecord customer = new CustomerRecord(1, @"Microsoft", @"Corporation");
+
+ try
+ {
+ sqlConnection.Open();
+
+ // Drop Objects if exists
+ dropObjects(sqlConnection, cmkName, cekName, tblName);
+
+ // Create Column Master Key with AKV Url
+ createCMK(sqlConnection, cmkName, akvProvider);
+ Console.WriteLine("Column Master Key created.");
+
+ // Create Column Encryption Key
+ createCEK(sqlConnection, cmkName, cekName, akvProvider);
+ Console.WriteLine("Column Encryption Key created.");
+
+ // Create Table with Encrypted Columns
+ createTbl(sqlConnection, cekName, tblName);
+ Console.WriteLine("Table created with Encrypted columns.");
+
+ // Insert Customer Record in table
+ insertData(sqlConnection, tblName, customer);
+ Console.WriteLine("Encryted data inserted.");
+
+ // Read data from table
+ verifyData(sqlConnection, tblName, customer);
+ Console.WriteLine("Data validated successfully.");
+ }
+ finally
+ {
+ // Drop table and keys
+ dropObjects(sqlConnection, cmkName, cekName, tblName);
+ Console.WriteLine("Dropped Table, CEK and CMK");
+ }
+
+ Console.WriteLine("Completed AKV provider Sample.");
+ }
+ }
+
+ private static void createCMK(SqlConnection sqlConnection, string cmkName, SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
+ {
+ string KeyStoreProviderName = SqlColumnEncryptionAzureKeyVaultProvider.ProviderName;
+
+ byte[] cmkSign = sqlColumnEncryptionAzureKeyVaultProvider.SignColumnMasterKeyMetadata(s_akvUrl, true);
+ string cmkSignStr = string.Concat("0x", BitConverter.ToString(cmkSign).Replace("-", string.Empty));
+
+ string sql =
+ $@"CREATE COLUMN MASTER KEY [{cmkName}]
+ WITH (
+ KEY_STORE_PROVIDER_NAME = N'{KeyStoreProviderName}',
+ KEY_PATH = N'{s_akvUrl}',
+ ENCLAVE_COMPUTATIONS (SIGNATURE = {cmkSignStr})
+ );";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static void createCEK(SqlConnection sqlConnection, string cmkName, string cekName, SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
+ {
+ string sql =
+ $@"CREATE COLUMN ENCRYPTION KEY [{cekName}]
+ WITH VALUES (
+ COLUMN_MASTER_KEY = [{cmkName}],
+ ALGORITHM = '{s_algorithm}',
+ ENCRYPTED_VALUE = {GetEncryptedValue(sqlColumnEncryptionAzureKeyVaultProvider)}
+ )";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static string GetEncryptedValue(SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider)
+ {
+ byte[] plainTextColumnEncryptionKey = new byte[32];
+ RandomNumberGenerator rng = RandomNumberGenerator.Create();
+ rng.GetBytes(plainTextColumnEncryptionKey);
+
+ byte[] encryptedColumnEncryptionKey = sqlColumnEncryptionAzureKeyVaultProvider.EncryptColumnEncryptionKey(s_akvUrl, s_algorithm, plainTextColumnEncryptionKey);
+ string EncryptedValue = string.Concat("0x", BitConverter.ToString(encryptedColumnEncryptionKey).Replace("-", string.Empty));
+ return EncryptedValue;
+ }
+
+ private static void createTbl(SqlConnection sqlConnection, string cekName, string tblName)
+ {
+ string ColumnEncryptionAlgorithmName = @"AEAD_AES_256_CBC_HMAC_SHA_256";
+
+ string sql =
+ $@"CREATE TABLE [dbo].[{tblName}]
+ (
+ [CustomerId] [int] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
+ [FirstName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = '{ColumnEncryptionAlgorithmName}'),
+ [LastName] [nvarchar](50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [{cekName}], ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = '{ColumnEncryptionAlgorithmName}')
+ )";
+
+ using (SqlCommand command = sqlConnection.CreateCommand())
+ {
+ command.CommandText = sql;
+ command.ExecuteNonQuery();
+ }
+ }
+
+ private static void insertData(SqlConnection sqlConnection, string tblName, CustomerRecord customer)
+ {
+ string insertSql = $"INSERT INTO [{tblName}] (CustomerId, FirstName, LastName) VALUES (@CustomerId, @FirstName, @LastName);";
+
+ using (SqlTransaction sqlTransaction = sqlConnection.BeginTransaction())
+ using (SqlCommand sqlCommand = new SqlCommand(insertSql,
+ connection: sqlConnection, transaction: sqlTransaction,
+ columnEncryptionSetting: SqlCommandColumnEncryptionSetting.Enabled))
+ {
+ sqlCommand.Parameters.AddWithValue(@"CustomerId", customer.Id);
+ sqlCommand.Parameters.AddWithValue(@"FirstName", customer.FirstName);
+ sqlCommand.Parameters.AddWithValue(@"LastName", customer.LastName);
+
+ sqlCommand.ExecuteNonQuery();
+ sqlTransaction.Commit();
+ }
+ }
+
+ private static void verifyData(SqlConnection sqlConnection, string tblName, CustomerRecord customer)
+ {
+ // Test INPUT parameter on an encrypted parameter
+ using (SqlCommand sqlCommand = new SqlCommand($"SELECT CustomerId, FirstName, LastName FROM [{tblName}] WHERE FirstName = @firstName", sqlConnection))
+ {
+ SqlParameter customerFirstParam = sqlCommand.Parameters.AddWithValue(@"firstName", @"Microsoft");
+ customerFirstParam.Direction = System.Data.ParameterDirection.Input;
+ customerFirstParam.ForceColumnEncryption = true;
+
+ using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
+ {
+ ValidateResultSet(sqlDataReader);
+ }
+ }
+ }
+
+ private static void ValidateResultSet(SqlDataReader sqlDataReader)
+ {
+ Console.WriteLine(" * Row available: " + sqlDataReader.HasRows);
+
+ while (sqlDataReader.Read())
+ {
+ if (sqlDataReader.GetInt32(0) == 1)
+ {
+ Console.WriteLine(" * Employee Id received as sent: " + sqlDataReader.GetInt32(0));
+ }
+ else
+ {
+ Console.WriteLine("Employee Id didn't match");
+ }
+
+ if (sqlDataReader.GetString(1) == @"Microsoft")
+ {
+ Console.WriteLine(" * Employee Firstname received as sent: " + sqlDataReader.GetString(1));
+ }
+ else
+ {
+ Console.WriteLine("Employee FirstName didn't match.");
+ }
+
+ if (sqlDataReader.GetString(2) == @"Corporation")
+ {
+ Console.WriteLine(" * Employee LastName received as sent: " + sqlDataReader.GetString(2));
+ }
+ else
+ {
+ Console.WriteLine("Employee LastName didn't match.");
+ }
+ }
+ }
+
+ private static void dropObjects(SqlConnection sqlConnection, string cmkName, string cekName, string tblName)
+ {
+ using (SqlCommand cmd = sqlConnection.CreateCommand())
+ {
+ cmd.CommandText = $@"IF EXISTS (select * from sys.objects where name = '{tblName}') BEGIN DROP TABLE [{tblName}] END";
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = $@"IF EXISTS (select * from sys.column_encryption_keys where name = '{cekName}') BEGIN DROP COLUMN ENCRYPTION KEY [{cekName}] END";
+ cmd.ExecuteNonQuery();
+ cmd.CommandText = $@"IF EXISTS (select * from sys.column_master_keys where name = '{cmkName}') BEGIN DROP COLUMN MASTER KEY [{cmkName}] END";
+ cmd.ExecuteNonQuery();
+ }
+ }
+
+ private class CustomerRecord
+ {
+ internal int Id { get; set; }
+ internal string FirstName { get; set; }
+ internal string LastName { get; set; }
+
+ public CustomerRecord(int id, string fName, string lName)
+ {
+ Id = id;
+ FirstName = fName;
+ LastName = lName;
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/AzureKeyVaultProvider_ColumnEncryptionKeyCacheScope.cs b/doc/samples/AzureKeyVaultProvider_ColumnEncryptionKeyCacheScope.cs
new file mode 100644
index 0000000000..c91e3edd7c
--- /dev/null
+++ b/doc/samples/AzureKeyVaultProvider_ColumnEncryptionKeyCacheScope.cs
@@ -0,0 +1,20 @@
+//
+class Program
+{
+ static void Main()
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ using (SqlCommand command = connection.CreateCommand())
+ {
+ Dictionary customKeyStoreProviders = new Dictionary();
+ SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider();
+ customKeyStoreProviders.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
+ command.RegisterColumnEncryptionKeyStoreProvidersOnCommand(customKeyStoreProviders);
+ // Perform database operation using Azure Key Vault Provider
+ // Any decrypted column encryption keys will be cached
+ } // Column encryption key cache of "azureKeyVaultProvider" is cleared when "azureKeyVaultProvider" goes out of scope
+ }
+ }
+}
+//
diff --git a/doc/samples/CustomDeviceCodeFlowAzureAuthenticationProvider.cs b/doc/samples/CustomDeviceCodeFlowAzureAuthenticationProvider.cs
index 19bc1f849d..68d792fef5 100644
--- a/doc/samples/CustomDeviceCodeFlowAzureAuthenticationProvider.cs
+++ b/doc/samples/CustomDeviceCodeFlowAzureAuthenticationProvider.cs
@@ -44,6 +44,7 @@ public class Program
{
public static void Main()
{
+ // Register our custom authentication provider class to override Active Directory Device Code Flow
SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, new CustomDeviceCodeFlowAzureAuthenticationProvider());
using (SqlConnection sqlConnection = new SqlConnection("Server=.database.windows.net;Authentication=Active Directory Device Code Flow;Database=;"))
{
diff --git a/doc/samples/IBinarySerialize.cs b/doc/samples/IBinarySerialize.cs
index 749ee5f3f6..64f314f86d 100644
--- a/doc/samples/IBinarySerialize.cs
+++ b/doc/samples/IBinarySerialize.cs
@@ -2,7 +2,7 @@
using System.IO;
using System.Data;
using System.Data.SqlTypes;
-using Microsoft.Data.SqlClient.Server;
+using Microsoft.SqlServer.Server;
using System.Text;
namespace test
@@ -45,7 +45,7 @@ static void Main(string[] args)
// Bytes 0 - 19: string text, padded to the right with null characters
// Bytes 20+: Double value
- // using Microsoft.Data.SqlClient.Server;
+ // using Microsoft.SqlServer.Server;
public void Read(System.IO.BinaryReader r)
{
@@ -84,7 +84,7 @@ public void Read(System.IO.BinaryReader r)
// Bytes 0 - 19: string text, padded to the right with null characters
// Bytes 20+: Double value
- // using Microsoft.Data.SqlClient.Server;
+ // using Microsoft.SqlServer.Server;
public void Write(System.IO.BinaryWriter w)
{
int maxStringSize = 20;
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_IBinarySerialize_Sample.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_IBinarySerialize_Sample.cs
new file mode 100644
index 0000000000..3631912ba6
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_IBinarySerialize_Sample.cs
@@ -0,0 +1,104 @@
+using System;
+using System.IO;
+using Microsoft.SqlServer.Server;
+
+namespace test
+{
+ public class Class1 : IBinarySerialize
+ {
+ [STAThread]
+ static void Main(string[] args)
+ {
+ string fileName = "info.dat";
+ Class1 temp = new Class1();
+
+ FileStream fs = new FileStream(fileName, FileMode.Create);
+ BinaryWriter w = new BinaryWriter(fs);
+
+ temp.Write(w);
+
+ w.Close();
+ fs.Close();
+
+ fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
+ BinaryReader r = new BinaryReader(fs);
+
+ temp.Read(r);
+
+ Console.WriteLine("String value: " + temp.StringValue);
+ Console.WriteLine("Double value: " + temp.DoubleValue);
+
+ r.Close();
+ fs.Close();
+ }
+
+ public string StringValue;
+ public double DoubleValue;
+
+ //
+ // The binary layout is as follows:
+ // Bytes 0 - 19: string text, padded to the right with null characters
+ // Bytes 20+: Double value
+
+ // using Microsoft.SqlServer.Server;
+ public void Read(System.IO.BinaryReader r)
+ {
+
+ int maxStringSize = 20;
+ char[] chars;
+ int stringEnd;
+ string stringValue;
+ double doubleValue;
+
+ // Read the characters from the binary stream.
+ chars = r.ReadChars(maxStringSize);
+
+ // Find the start of the null character padding.
+ stringEnd = Array.IndexOf(chars, '\0');
+
+ if (stringEnd == 0)
+ {
+ stringValue = null;
+ return;
+ }
+
+ // Build the string from the array of characters.
+ stringValue = new String(chars, 0, stringEnd);
+
+ // Read the double value from the binary stream.
+ doubleValue = r.ReadDouble();
+
+ // Set the object's properties equal to the values.
+ this.StringValue = stringValue;
+ this.DoubleValue = doubleValue;
+ }
+ //
+
+ //
+ // The binary layout is as follows:
+ // Bytes 0 - 19: string text, padded to the right with null characters
+ // Bytes 20+: Double value
+
+ // using Microsoft.SqlServer.Server;
+ public void Write(System.IO.BinaryWriter w)
+ {
+ int maxStringSize = 20;
+ string stringValue = "The value of PI: ";
+ string paddedString;
+ double value = 3.14159;
+
+ // Pad the string from the right with null characters.
+ paddedString = stringValue.PadRight(maxStringSize, '\0');
+
+ // Write the string value one byte at a time.
+ for (int i = 0; i < paddedString.Length; i++)
+ {
+ w.Write(paddedString[i]);
+ }
+
+ // Write the double value.
+ w.Write(value);
+ }
+ //
+ }
+}
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlFunctionAttribute_Sample.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlFunctionAttribute_Sample.cs
new file mode 100644
index 0000000000..e35b9cad21
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlFunctionAttribute_Sample.cs
@@ -0,0 +1,23 @@
+using System.IO;
+using System.Collections;
+using Microsoft.SqlServer.Server;
+
+public class Class1
+{
+
+//
+[SqlFunctionAttribute(FillRowMethodName = "FillFileRow")]
+public static IEnumerable GetFileDetails(string directoryPath)
+{
+ try
+ {
+ DirectoryInfo di = new DirectoryInfo(directoryPath);
+ return di.GetFiles();
+ }
+ catch (DirectoryNotFoundException dnf)
+ {
+ return new string[1] { dnf.ToString() };
+ }
+}
+//
+}
\ No newline at end of file
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedAggregateAttribute_Sample.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedAggregateAttribute_Sample.cs
new file mode 100644
index 0000000000..34999b5dd5
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedAggregateAttribute_Sample.cs
@@ -0,0 +1,23 @@
+//
+using System;
+using System.IO;
+using Microsoft.SqlServer.Server;
+
+[Serializable]
+[SqlUserDefinedAggregate(Microsoft.SqlServer.Server.Format.UserDefined,
+ IsInvariantToNulls = true,
+ IsInvariantToDuplicates = false,
+ IsInvariantToOrder = false,
+ MaxByteSize = 8000)
+ ]
+public class Concatenate : Microsoft.SqlServer.Server.IBinarySerialize
+{
+ public void Read(BinaryReader r)
+ {
+ }
+
+ public void Write(BinaryWriter w)
+ {
+ }
+}
+//
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedTypeAttribute_Sample.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedTypeAttribute_Sample.cs
new file mode 100644
index 0000000000..90bfccfce4
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedTypeAttribute_Sample.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Data.SqlTypes;
+using Microsoft.SqlServer.Server;
+using System.Text;
+
+//
+[Serializable]
+[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,
+ IsByteOrdered=true,
+ Name="Point",ValidationMethodName = "ValidatePoint")]
+public struct Point : INullable
+{
+//
+ private bool is_Null;
+ private int _x;
+ private int _y;
+
+ public bool IsNull
+ {
+ get
+ {
+ return (is_Null);
+ }
+ }
+
+ public static Point Null
+ {
+ get
+ {
+ Point pt = new Point();
+ pt.is_Null = true;
+ return pt;
+ }
+ }
+
+ // Use StringBuilder to provide string representation of UDT.
+ public override string ToString()
+ {
+ // Since InvokeIfReceiverIsNull defaults to 'true'
+ // this test is unnecessary if Point is only being called
+ // from SQL.
+ if (this.IsNull)
+ {
+ return "NULL";
+ }
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(_x);
+ builder.Append(",");
+ builder.Append(_y);
+ return builder.ToString();
+ }
+ }
+
+ [SqlMethod(OnNullCall = false)]
+ public static Point Parse(SqlString s)
+ {
+ // With OnNullCall=false, this check is unnecessary if
+ // Point only called from SQL.
+ if (s.IsNull)
+ return Null;
+
+ // Parse input string to separate out points.
+ Point pt = new Point();
+ string[] xy = s.Value.Split(",".ToCharArray());
+ pt.X = int.Parse(xy[0]);
+ pt.Y = int.Parse(xy[1]);
+
+ // Call ValidatePoint to enforce validation
+ // for string conversions.
+ if (!pt.ValidatePoint())
+ throw new ArgumentException("Invalid XY coordinate values.");
+ return pt;
+ }
+
+ // X and Y coordinates exposed as properties.
+ public int X
+ {
+ get
+ {
+ return this._x;
+ }
+ // Call ValidatePoint to ensure valid range of Point values.
+ set
+ {
+ int temp = _x;
+ _x = value;
+ if (!ValidatePoint())
+ {
+ _x = temp;
+ throw new ArgumentException("Invalid X coordinate value.");
+ }
+ }
+ }
+
+ public int Y
+ {
+ get
+ {
+ return this._y;
+ }
+ set
+ {
+ int temp = _y;
+ _y = value;
+ if (!ValidatePoint())
+ {
+ _y = temp;
+ throw new ArgumentException("Invalid Y coordinate value.");
+ }
+ }
+ }
+
+ // Validation method to enforce valid X and Y values.
+ private bool ValidatePoint()
+ {
+ return true;
+ }
+}
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/SqlFunctionAttribute_SqlFunction.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlFunctionAttribute_SqlFunction.cs
new file mode 100644
index 0000000000..7317b1917b
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlFunctionAttribute_SqlFunction.cs
@@ -0,0 +1,45 @@
+using System.Collections;
+//-----------------------------------------------------------------------------
+//
+using System.Data.SqlTypes;
+using Microsoft.SqlServer.Server;
+
+public partial class UserDefinedFunctions
+{
+ public const double SALES_TAX = .086;
+
+ [SqlFunction()]
+ public static SqlDouble addTax(SqlDouble originalAmount)
+ {
+ SqlDouble taxAmount = originalAmount * SALES_TAX;
+
+ return originalAmount + taxAmount;
+ }
+}
+//
+
+//-----------------------------------------------------------------------------
+//
+public partial class UserDefinedFunctions
+{
+ [SqlFunction(Name="sp_scalarFunc")]
+ public static SqlString SampleScalarFunction(SqlString s)
+ {
+ //...
+ return "";
+ }
+}
+//
+
+//-----------------------------------------------------------------------------
+//
+public partial class UserDefinedFunctions
+{
+ [SqlFunction(Name="sp_tableFunc", TableDefinition="letter nchar(1)")]
+ public static IEnumerable SampleTableFunction(SqlString s)
+ {
+ //...
+ return new ArrayList(new char[3] {'a', 'b', 'c'});
+ }
+}
+//
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/SqlMethod.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlMethod.cs
new file mode 100644
index 0000000000..9e41150c99
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlMethod.cs
@@ -0,0 +1,126 @@
+using System;
+//
+using Microsoft.SqlServer.Server;
+using System.Data.SqlTypes;
+using System.Text;
+
+[Serializable]
+[SqlUserDefinedType(Format.Native,
+ IsByteOrdered = true,
+ Name = "Point", ValidationMethodName = "ValidatePoint")]
+public struct Point : INullable
+{
+
+ private bool is_Null;
+ private int _x;
+ private int _y;
+
+ // Distance from Point to the specified x and y values method.
+ [SqlMethod(OnNullCall = false, IsMutator = false, InvokeIfReceiverIsNull = false)]
+ public Double DistanceFromXY(int iX, int iY)
+ {
+ return Math.Sqrt(Math.Pow(iX - _x, 2.0) + Math.Pow(iY - _y, 2.0));
+ }
+ //
+
+ public bool IsNull
+ {
+ get
+ {
+ return (is_Null);
+ }
+ }
+
+ public static Point Null
+ {
+ get
+ {
+ Point pt = new Point();
+ pt.is_Null = true;
+ return pt;
+ }
+ }
+
+ // Use StringBuilder to provide string representation of UDT.
+ public override string ToString()
+ {
+ // Since InvokeIfReceiverIsNull defaults to 'true'
+ // this test is unnecessary if Point is only being called
+ // from SQL.
+ if (this.IsNull)
+ return "NULL";
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append(_x);
+ builder.Append(",");
+ builder.Append(_y);
+ return builder.ToString();
+ }
+ }
+
+ [SqlMethod(OnNullCall = false)]
+ public static Point Parse(SqlString s)
+ {
+ // With OnNullCall=false, this check is unnecessary if
+ // Point only called from SQL.
+ if (s.IsNull)
+ return Null;
+
+ // Parse input string to separate out points.
+ Point pt = new Point();
+ string[] xy = s.Value.Split(",".ToCharArray());
+ pt.X = int.Parse(xy[0]);
+ pt.Y = int.Parse(xy[1]);
+
+ // Call ValidatePoint to enforce validation
+ // for string conversions.
+ if (!pt.ValidatePoint())
+ throw new ArgumentException("Invalid XY coordinate values.");
+ return pt;
+ }
+
+ // X and Y coordinates exposed as properties.
+ public int X
+ {
+ get
+ {
+ return this._x;
+ }
+ // Call ValidatePoint to ensure valid range of Point values.
+ set
+ {
+ int temp = _x;
+ _x = value;
+ if (!ValidatePoint())
+ {
+ _x = temp;
+ throw new ArgumentException("Invalid X coordinate value.");
+ }
+ }
+ }
+
+ public int Y
+ {
+ get
+ {
+ return this._y;
+ }
+ set
+ {
+ int temp = _y;
+ _y = value;
+ if (!ValidatePoint())
+ {
+ _y = temp;
+ throw new ArgumentException("Invalid Y coordinate value.");
+ }
+ }
+ }
+
+ // Validation method to enforce valid X and Y values.
+ private bool ValidatePoint()
+ {
+ return true;
+ }
+}
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/SqlUserDefinedAggregateAttribute_Aggregate1.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlUserDefinedAggregateAttribute_Aggregate1.cs
new file mode 100644
index 0000000000..edf119d940
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlUserDefinedAggregateAttribute_Aggregate1.cs
@@ -0,0 +1,59 @@
+//-----------------------------------------------------------------------------
+//
+using System;
+using System.Data.SqlTypes;
+using Microsoft.SqlServer.Server;
+
+[Serializable]
+[SqlUserDefinedAggregate(Format.Native)]
+public struct CountVowels
+{
+ // count only the vowels in the passed-in strings
+ private SqlInt32 countOfVowels;
+
+ public void Init()
+ {
+ countOfVowels = 0;
+ }
+
+ public void Accumulate(SqlString value)
+ {
+ // list of vowels to look for
+ string vowels = "aeiou";
+
+ // for each character in the given parameter
+ for (int i=0; i < value.ToString().Length; i++)
+ {
+ // for each character in the vowels string
+ for (int j=0; j < vowels.Length; j++)
+ {
+ // convert parameter character to lowercase and compare to vowel
+ if (value.Value.Substring(i,1).ToLower() == vowels.Substring(j,1))
+ {
+ // it is a vowel, increment the count
+ countOfVowels+=1;
+ }
+ }
+ }
+ }
+
+ public void Merge(CountVowels value)
+ {
+ Accumulate(value.Terminate());
+ }
+
+ public SqlString Terminate()
+ {
+ return countOfVowels.ToString();
+ }
+}
+//
+
+//-----------------------------------------------------------------------------
+//
+[SqlUserDefinedAggregate(Format.Native)]
+public class SampleAggregate
+{
+ //...
+}
+//
diff --git a/doc/samples/Microsoft.SqlServer.Server/csharp/SqlUserDefinedTypeAttribute_Type1.cs b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlUserDefinedTypeAttribute_Type1.cs
new file mode 100644
index 0000000000..70f8d0ae7b
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/csharp/SqlUserDefinedTypeAttribute_Type1.cs
@@ -0,0 +1,133 @@
+//-----------------------------------------------------------------------------
+//
+using System;
+using System.Data.SqlTypes;
+using Microsoft.SqlServer.Server;
+
+[Serializable()]
+[SqlUserDefinedType(Format.Native)]
+public struct Point : INullable
+{
+ private int m_x;
+ private int m_y;
+ private bool is_Null;
+
+ public int X
+ {
+ get
+ {
+ return (this.m_x);
+ }
+ set
+ {
+ m_x = value;
+ }
+ }
+
+ public int Y
+ {
+ get
+ {
+ return (this.m_y);
+ }
+ set
+ {
+ m_y = value;
+ }
+ }
+
+ public bool IsNull
+ {
+ get
+ {
+ return is_Null;
+ }
+ }
+
+ public static Point Null
+ {
+ get
+ {
+ Point pt = new Point();
+ pt.is_Null = true;
+ return (pt);
+ }
+ }
+
+ public override string ToString()
+ {
+ if (this.IsNull)
+ {
+ return "NULL";
+ }
+ else
+ {
+ return this.m_x + ":" + this.m_y;
+ }
+ }
+
+ public static Point Parse(SqlString s)
+ {
+ if (s.IsNull)
+ {
+ return Null;
+ }
+
+ // Parse input string here to separate out coordinates
+ string str = Convert.ToString(s);
+ string[] xy = str.Split(':');
+
+ Point pt = new Point();
+ pt.X = Convert.Toint(xy[0]);
+ pt.Y = Convert.Toint(xy[1]);
+ return (pt);
+ }
+
+ public SqlString Quadrant()
+ {
+ if (m_x == 0 && m_y == 0)
+ {
+ return "centered";
+ }
+
+ SqlString stringReturn = "";
+
+ if (m_x == 0)
+ {
+ stringReturn = "center";
+ }
+ else if (m_x > 0)
+ {
+ stringReturn = "right";
+ }
+ else if (m_x < 0)
+ {
+ stringReturn = "left";
+ }
+
+ if (m_y == 0)
+ {
+ stringReturn = stringReturn + " center";
+ }
+ else if (m_y > 0)
+ {
+ stringReturn = stringReturn + " top";
+ }
+ else if (m_y < 0)
+ {
+ stringReturn = stringReturn + " bottom";
+ }
+
+ return stringReturn;
+ }
+}
+//
+
+//-----------------------------------------------------------------------------
+//
+[SqlUserDefinedType(Format.Native, MaxByteSize=8000)]
+public class SampleType
+{
+ //...
+}
+//
diff --git a/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_IBinarySerialize_Sample.vb b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_IBinarySerialize_Sample.vb
new file mode 100644
index 0000000000..8f96b056a4
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_IBinarySerialize_Sample.vb
@@ -0,0 +1,103 @@
+Option Explicit On
+Option Strict On
+
+Imports System
+Imports System.IO
+Imports Microsoft.SqlServer.Server
+Imports System.Text
+
+Public Class Class1:Implements Microsoft.SqlServer.Server.IBinarySerialize
+
+Dim StringValue As String
+Dim DoubleValue As Double
+
+Shared Sub Main()
+
+ Dim fileName As String = "info.dat"
+ Dim temp As New Class1()
+
+ Dim fs As New FileStream(fileName, FileMode.Create)
+ Dim w As New BinaryWriter(fs)
+
+ temp.Write(w)
+
+ w.Close()
+ fs.Close()
+
+ fs = New FileStream(fileName, FileMode.Open, FileAccess.Read)
+ Dim r As New BinaryReader(fs)
+
+ temp.Read(r)
+
+ Console.WriteLine("String Value: " & temp.StringValue)
+ Console.WriteLine("Double value: " & temp.DoubleValue)
+
+End Sub
+
+'
+' The binary layout is as follows:
+' Bytes 0 - 19: string text, padded to the right with null
+' characters
+' Bytes 20+: double value
+Public Sub Read(ByVal r As System.IO.BinaryReader) _
+ Implements Microsoft.SqlServer.Server.IBinarySerialize.Read
+
+ Dim maxStringSize As Integer = 20
+ Dim chars As Char()
+ Dim stringEnd As Integer
+ Dim stringValue As String
+ Dim value As double
+
+ ' Read the characters from the binary stream.
+ chars = r.ReadChars(maxStringSize)
+
+ ' Find the start of the null character padding.
+ stringEnd = Array.IndexOf(chars, ControlChars.NullChar)
+
+ If StringEnd = 0 Then
+ stringValue = Nothing
+ Exit Sub
+ End If
+
+ ' Build the string from the array of characters.
+ stringValue = new String(chars, 0, stringEnd)
+
+ ' Read the double value from the binary stream.
+ value = r.ReadDouble()
+
+ ' Set the object's properties equal to the values.
+ Me.StringValue = stringValue
+ Me.DoubleValue = value
+
+End Sub
+'
+
+'
+' The binary layout is as follows:
+' Bytes 0 - 19: string text, padded to the right with null characters
+' Bytes 20+: Double value
+Public Sub Write(ByVal w As System.IO.BinaryWriter) _
+ Implements Microsoft.SqlServer.Server.IBinarySerialize.Write
+
+ Dim maxStringSize As Integer = 20
+ Dim stringValue As String = "The value of PI: "
+ Dim paddedString As String
+ Dim value As Double = 3.14159
+
+ ' Pad the string from the right with null characters.
+ paddedString = stringValue.PadRight(maxStringSize, ControlChars.NullChar)
+
+
+ ' Write the string value one byte at a time.
+ Dim i As Integer
+ For i = 0 To paddedString.Length - 1
+ w.Write(paddedString(i))
+ Next
+
+ ' Write the double value.
+ w.Write(value)
+
+End Sub
+'
+
+End Class
diff --git a/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlFunctionAttribute_Sample.vb b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlFunctionAttribute_Sample.vb
new file mode 100644
index 0000000000..41c7bcffcc
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlFunctionAttribute_Sample.vb
@@ -0,0 +1,31 @@
+Option Explicit On
+Option Strict On
+
+Imports System.IO
+Imports System.Collections
+Imports Microsoft.SqlServer.Server
+
+Public Class Class1
+
+'
+ _
+Public Shared Function GetFileDetails(ByVal directoryPath As String) As IEnumerable
+
+ Try
+
+ Dim di As DirectoryInfo = new DirectoryInfo(directoryPath)
+ return di.GetFiles()
+
+ Catch dnf As DirectoryNotFoundException
+
+ Dim message As String() = {dnf.ToString() }
+ return message
+
+ End Try
+End Function
+'
+
+
+
+
+End Class
\ No newline at end of file
diff --git a/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedAggregateAttribute_Sample.vb b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedAggregateAttribute_Sample.vb
new file mode 100644
index 0000000000..2bb1e5af98
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedAggregateAttribute_Sample.vb
@@ -0,0 +1,21 @@
+'
+Imports System.IO
+Imports Microsoft.SqlServer.Server
+
+ _
+Public Class Concatenate
+ Implements Microsoft.SqlServer.Server.IBinarySerialize
+
+Public Sub Read(ByVal r As BinaryReader) Implements Microsoft.SqlServer.Server.IBinarySerialize.Read
+
+ End Sub
+
+ Public Sub Write(ByVal w As BinaryWriter) Implements Microsoft.SqlServer.Server.IBinarySerialize.Write
+
+ End Sub
+End Class
+'
diff --git a/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedTypeAttribute_Sample.vb b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedTypeAttribute_Sample.vb
new file mode 100644
index 0000000000..e5b2368aa9
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedTypeAttribute_Sample.vb
@@ -0,0 +1,114 @@
+Option Explicit On
+Option Strict On
+
+Imports System.Data.SqlTypes
+Imports Microsoft.SqlServer.Server
+Imports System.Text
+
+'
+ _
+ Public Structure Point
+ Implements INullable
+'
+ Private is_Null As Boolean
+ Private _x As Integer
+ Private _y As Integer
+
+ Public ReadOnly Property IsNull() As Boolean _
+ Implements INullable.IsNull
+ Get
+ Return (is_Null)
+ End Get
+ End Property
+
+ Public Shared ReadOnly Property Null() As Point
+ Get
+ Dim pt As New Point
+ pt.is_Null = True
+ Return (pt)
+ End Get
+ End Property
+
+ ' Use StringBuilder to provide string representation of UDT.
+ Public Overrides Function ToString() As String
+ ' Since InvokeIfReceiverIsNull defaults to 'true'
+ ' this test is unneccesary if Point is only being called
+ ' from SQL.
+ If Me.IsNull Then
+ Return "NULL"
+ Else
+ Dim builder As StringBuilder = New StringBuilder
+ builder.Append(_x)
+ builder.Append(",")
+ builder.Append(_y)
+ Return builder.ToString
+ End If
+ End Function
+
+ _
+ Public Shared Function Parse(ByVal s As SqlString) As Point
+ ' With OnNullCall=False, this check is unnecessary if
+ ' Point only being called from SQL.
+ If s.IsNull Then
+ Return Null
+ End If
+
+ ' Parse input string here to separate out points.
+ Dim pt As New Point()
+ Dim xy() As String = s.Value.Split(",".ToCharArray())
+ pt.X = Integer.Parse(xy(0))
+ pt.Y = Integer.Parse(xy(1))
+
+ ' Call ValidatePoint to enforce validation
+ ' for string conversions.
+ If Not pt.ValidatePoint() Then
+ Throw New ArgumentException("Invalid XY coordinate values.")
+ End If
+ Return pt
+ End Function
+
+ ' X and Y coordinates are exposed as properties.
+ Public Property X() As Integer
+ Get
+ Return (Me._x)
+ End Get
+
+ Set(ByVal Value As Integer)
+ Dim temp As Integer = _x
+ _x = Value
+ If Not ValidatePoint() Then
+ _x = temp
+ Throw New ArgumentException("Invalid X coordinate value.")
+ End If
+ End Set
+ End Property
+
+ Public Property Y() As Integer
+ Get
+ Return (Me._y)
+ End Get
+
+ Set(ByVal Value As Integer)
+ Dim temp As Integer = _y
+ _y = Value
+ If Not ValidatePoint() Then
+ _y = temp
+ Throw New ArgumentException("Invalid Y coordinate value.")
+ End If
+ End Set
+ End Property
+
+ ' Validation method to enforce valid X and Y values.
+ Private Function ValidatePoint() As Boolean
+ ' Allow only zero or positive integers for X and Y coordinates.
+ If (_x >= 0) And (_y >= 0) Then
+ Return True
+ Else
+ Return False
+ End If
+ End Function
+
+End Structure
diff --git a/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlFunctionAttribute_SqlFunction.vb b/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlFunctionAttribute_SqlFunction.vb
new file mode 100644
index 0000000000..b308062cd4
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlFunctionAttribute_SqlFunction.vb
@@ -0,0 +1,47 @@
+Imports System.Collections
+'------------------------------------------------------------------------------
+'
+Imports System.Data.SqlTypes
+Imports Microsoft.SqlServer.Server
+
+Partial Public Class UserDefinedFunctions
+
+ Public Const SALES_TAX As Double = 0.086
+
+
+ Public Shared Function addTax(ByVal originalAmount As SqlDouble) As SqlDouble
+
+ Dim taxAmount As SqlDouble = originalAmount * SALES_TAX
+
+ Return originalAmount + taxAmount
+ End Function
+End Class
+'
+
+
+'------------------------------------------------------------------------------
+'
+Partial Public Class UserDefinedFunctions
+
+
+ Public Shared Function SampleScalarFunction(ByVal s As SqlString) As SqlString
+
+ '...
+ Return ""
+ End Function
+End Class
+'
+
+
+'------------------------------------------------------------------------------
+'
+Partial Public Class UserDefinedFunctions
+
+
+ Public Shared Function SampleTableFunction(ByVal s As SqlString) As IEnumerable
+
+ '...
+ Return New Char(2) {"a"c, "b"c, "c"c}
+ End Function
+End Class
+'
diff --git a/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlUserDefinedAggregateAttribute_Aggregate1.vb b/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlUserDefinedAggregateAttribute_Aggregate1.vb
new file mode 100644
index 0000000000..b2e7727c51
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlUserDefinedAggregateAttribute_Aggregate1.vb
@@ -0,0 +1,57 @@
+'------------------------------------------------------------------------------
+'
+Imports System
+Imports System.Data.SqlTypes
+Imports Microsoft.SqlServer.Server
+
+
+
+Public Structure CountVowels
+
+ ' count only the vowels in the passed-in strings
+ Private countOfVowels As SqlInt32
+
+
+ Public Sub Init()
+ countOfVowels = 0
+ End Sub
+
+
+ Public Sub Accumulate(ByVal value As SqlString)
+ Dim stringChar As String
+ Dim indexChar As Integer
+
+ ' for each character in the given parameter
+ For indexChar = 0 To Len(value.ToString()) - 1
+
+ stringChar = value.ToString().Substring(indexChar, 1)
+
+ If stringChar.ToLower() Like "[aeiou]" Then
+
+ ' it is a vowel, increment the count
+ countOfVowels = countOfVowels + 1
+ End If
+ Next
+ End Sub
+
+
+ Public Sub Merge(ByVal value As CountVowels)
+
+ Accumulate(value.Terminate())
+ End Sub
+
+
+ Public Function Terminate() As SqlString
+
+ Return countOfVowels.ToString()
+ End Function
+End Structure
+'
+
+'------------------------------------------------------------------------------
+'
+
+Public Class SampleAggregate
+ '...
+End Class
+'
diff --git a/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlUserDefinedTypeAttribute_Type1.vb b/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlUserDefinedTypeAttribute_Type1.vb
new file mode 100644
index 0000000000..effdf6bda4
--- /dev/null
+++ b/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlUserDefinedTypeAttribute_Type1.vb
@@ -0,0 +1,116 @@
+'------------------------------------------------------------------------------
+'
+Imports System.Data.SqlTypes
+Imports Microsoft.SqlServer.Server
+
+
+
+Public Structure Point
+ Implements INullable
+
+ Private m_x As Integer
+ Private m_y As Integer
+ Private is_Null As Boolean
+
+ Public Property X() As Integer
+ Get
+ Return (Me.m_x)
+ End Get
+ Set(ByVal Value As Integer)
+ m_x = Value
+ End Set
+ End Property
+
+ Public Property Y() As Integer
+ Get
+ Return (Me.m_y)
+ End Get
+ Set(ByVal Value As Integer)
+ m_y = Value
+ End Set
+ End Property
+
+ Public ReadOnly Property IsNull() As Boolean Implements INullable.IsNull
+ Get
+ Return is_Null
+ End Get
+ End Property
+
+ Public Shared ReadOnly Property Null() As Point
+ Get
+ Dim pt As Point = New Point
+ pt.is_Null = True
+ Return pt
+ End Get
+ End Property
+
+ Public Overrides Function ToString() As String
+ If Me.IsNull() Then
+ Return Nothing
+ Else
+ Return Me.m_x & ":" & Me.m_y
+ End If
+ End Function
+
+ Public Shared Function Parse(ByVal s As SqlString) As Point
+ If s = SqlString.Null Then
+ Return Null
+ End If
+
+ If s.ToString() = SqlString.Null.ToString() Then
+ Return Null
+ End If
+
+ If s.IsNull Then
+ Return Null
+ End If
+
+ 'Parse input string here to separate out coordinates
+ Dim str As String = Convert.ToString(s)
+ Dim xy() As String = str.Split(":"c)
+
+ Dim pt As New Point()
+ pt.X = CType(xy(0), Integer)
+ pt.Y = CType(xy(1), Integer)
+ Return (pt)
+ End Function
+
+ Public Function Quadrant() As SqlString
+
+ If m_x = 0 And m_y = 0 Then
+ Return "centered"
+ End If
+
+ Dim stringResult As String = ""
+
+ Select Case m_x
+ Case 0
+ stringResult = "center"
+ Case Is > 0
+ stringResult = "right"
+ Case Is < 0
+ stringResult = "left"
+ End Select
+
+ Select Case m_y
+ Case 0
+ stringResult = stringResult & " center"
+ Case Is > 0
+ stringResult = stringResult & " top"
+ Case Is < 0
+ stringResult = stringResult & " bottom"
+ End Select
+
+ Return stringResult
+ End Function
+End Structure
+'
+
+'------------------------------------------------------------------------------
+'
+
+Public Class SampleType
+
+ '...
+End Class
+'
diff --git a/doc/samples/RegisterCustomKeyStoreProvider_CommandPrecedence.cs b/doc/samples/RegisterCustomKeyStoreProvider_CommandPrecedence.cs
new file mode 100644
index 0000000000..d70410df59
--- /dev/null
+++ b/doc/samples/RegisterCustomKeyStoreProvider_CommandPrecedence.cs
@@ -0,0 +1,32 @@
+//
+class Program
+{
+ static void Main()
+ {
+ Dictionary customKeyStoreProviders = new Dictionary();
+ MyCustomKeyStoreProvider firstProvider = new MyCustomKeyStoreProvider();
+ customKeyStoreProviders.Add("FIRST_CUSTOM_STORE", firstProvider);
+ // Registers the provider globally
+ SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ customKeyStoreProviders.Clear();
+ MyCustomKeyStoreProvider secondProvider = new MyCustomKeyStoreProvider();
+ customKeyStoreProviders.Add("SECOND_CUSTOM_STORE", secondProvider);
+ // Registers the provider on the connection
+ connection.RegisterColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);
+
+ using (SqlCommand command = connection.CreateCommand())
+ {
+ customKeyStoreProviders.Clear();
+ SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider();
+ customKeyStoreProviders.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
+ // Registers the provider on the command
+ // These providers will take precedence over connection-level providers and globally registered providers
+ command.RegisterColumnEncryptionKeyStoreProvidersOnCommand(customKeyStoreProviders);
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/RegisterCustomKeyStoreProvider_ConnectionPrecedence.cs b/doc/samples/RegisterCustomKeyStoreProvider_ConnectionPrecedence.cs
new file mode 100644
index 0000000000..e51ec09c83
--- /dev/null
+++ b/doc/samples/RegisterCustomKeyStoreProvider_ConnectionPrecedence.cs
@@ -0,0 +1,23 @@
+//
+class Program
+{
+ static void Main()
+ {
+ Dictionary customKeyStoreProviders = new Dictionary();
+ MyCustomKeyStoreProvider myProvider = new MyCustomKeyStoreProvider();
+ customKeyStoreProviders.Add("MY_CUSTOM_STORE", myProvider);
+ // Registers the provider globally
+ SqlConnection.RegisterColumnEncryptionKeyStoreProviders(customKeyStoreProviders);
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ customKeyStoreProviders.Clear();
+ SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider = new SqlColumnEncryptionAzureKeyVaultProvider();
+ customKeyStoreProviders.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider);
+ // Registers the provider on the connection
+ // These providers will take precedence over globally registered providers
+ connection.RegisterColumnEncryptionKeyStoreProvidersOnConnection(customKeyStoreProviders);
+ }
+ }
+}
+//
diff --git a/doc/samples/RegisterCustomKeyStoreProvider_Example.cs b/doc/samples/RegisterCustomKeyStoreProvider_Example.cs
new file mode 100644
index 0000000000..334b1264c1
--- /dev/null
+++ b/doc/samples/RegisterCustomKeyStoreProvider_Example.cs
@@ -0,0 +1,51 @@
+//
+using Microsoft.Data.SqlClient;
+using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider;
+using System.Collections.Generic;
+
+class Program
+{
+ // Maps a SqlColumnEncryptionAzureKeyVaultProvider to some object that represents a user
+ static Dictionary
diff --git a/doc/samples/SqlClientDiagnosticCounter.cs b/doc/samples/SqlClientDiagnosticCounter.cs
new file mode 100644
index 0000000000..576563f6fd
--- /dev/null
+++ b/doc/samples/SqlClientDiagnosticCounter.cs
@@ -0,0 +1,62 @@
+//
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Tracing;
+using System.Linq;
+
+// This listener class will listen for events from the SqlClientEventSource class.
+// SqlClientEventSource is an implementation of the EventSource class which gives
+// it the ability to create events.
+public class EventCounterListener : EventListener
+{
+ protected override void OnEventSourceCreated(EventSource eventSource)
+ {
+ // Only enable events from SqlClientEventSource.
+ if (eventSource.Name.Equals("Microsoft.Data.SqlClient.EventSource"))
+ {
+ var options = new Dictionary();
+ // define time interval 1 second
+ // without defining this parameter event counters will not enabled
+ options.Add("EventCounterIntervalSec", "1");
+ // enable for the None keyword
+ EnableEvents(eventSource, EventLevel.Informational, EventKeywords.None, options);
+ }
+ }
+
+ // This callback runs whenever an event is written by SqlClientEventSource.
+ // Event data is accessed through the EventWrittenEventArgs parameter.
+ protected override void OnEventWritten(EventWrittenEventArgs eventData)
+ {
+ if (eventData.Payload.FirstOrDefault(p => p is IDictionary x && x.ContainsKey("Name")) is IDictionary counters)
+ {
+ if (counters.TryGetValue("DisplayName", out object name) && name is string cntName
+ && counters.TryGetValue("Mean", out object value) && value is double cntValue)
+ {
+ // print event counter's name and mean value
+ Console.WriteLine($"{cntName}\t\t{cntValue}");
+ }
+ }
+ }
+}
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ // Create a new event listener
+ using (var listener = new EventCounterListener())
+ {
+ string connectionString = "Data Source=localhost; Integrated Security=true";
+
+ for (int i = 0; i < 50; i++)
+ {
+ // Open a connection
+ SqlConnection cnn = new SqlConnection(connectionString);
+ cnn.Open();
+ // wait for sampling interval happens
+ System.Threading.Thread.Sleep(500);
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClientFactory_Netcoreapp.cs b/doc/samples/SqlClientFactory_Netcoreapp.cs
new file mode 100644
index 0000000000..e72d623067
--- /dev/null
+++ b/doc/samples/SqlClientFactory_Netcoreapp.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Data.Common;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main()
+ {
+ }
+
+ //
+ private static DbProviderFactory GetFactory()
+ {
+ // register SqlClientFactory in provider factories
+ DbProviderFactories.RegisterFactory("Microsoft.Data.SqlClient", SqlClientFactory.Instance);
+
+ return DbProviderFactories.GetFactory("Microsoft.Data.SqlClient");
+ }
+ //
+}
diff --git a/doc/samples/SqlClient_AsyncProgramming_Cancellation.cs b/doc/samples/SqlClient_AsyncProgramming_Cancellation.cs
new file mode 100644
index 0000000000..d60fc6f99b
--- /dev/null
+++ b/doc/samples/SqlClient_AsyncProgramming_Cancellation.cs
@@ -0,0 +1,45 @@
+using System;
+//
+using Microsoft.Data.SqlClient;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Samples
+{
+ class CancellationSample
+ {
+ public static void Main(string[] args)
+ {
+ CancellationTokenSource source = new CancellationTokenSource();
+ source.CancelAfter(2000); // give up after 2 seconds
+ try
+ {
+ Task result = CancellingAsynchronousOperations(source.Token);
+ result.Wait();
+ }
+ catch (AggregateException exception)
+ {
+ if (exception.InnerException is SqlException)
+ {
+ Console.WriteLine("Operation canceled");
+ }
+ else
+ {
+ throw;
+ }
+ }
+ }
+
+ static async Task CancellingAsynchronousOperations(CancellationToken cancellationToken)
+ {
+ using (SqlConnection connection = new SqlConnection("Server=(local);Integrated Security=true"))
+ {
+ await connection.OpenAsync(cancellationToken);
+
+ SqlCommand command = new SqlCommand("WAITFOR DELAY '00:10:00'", connection);
+ await command.ExecuteNonQueryAsync(cancellationToken);
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClient_AsyncProgramming_DistributedTransaction.cs b/doc/samples/SqlClient_AsyncProgramming_DistributedTransaction.cs
new file mode 100644
index 0000000000..a517e0ea40
--- /dev/null
+++ b/doc/samples/SqlClient_AsyncProgramming_DistributedTransaction.cs
@@ -0,0 +1,68 @@
+using System;
+//
+using Microsoft.Data.SqlClient;
+using System.Threading.Tasks;
+using System.Transactions;
+
+class Program
+{
+ public static void Main()
+ {
+ SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
+ // replace these with your own values
+ // create two tables RegionTable1 and RegionTable2
+ // and add a constraint in one of these tables
+ // to avoid duplicate RegionID
+ builder.DataSource = "localhost";
+ builder.InitialCatalog = "Northwind";
+ builder.IntegratedSecurity = true;
+
+ Task task = ExecuteDistributedTransaction(builder.ConnectionString, builder.ConnectionString);
+ task.Wait();
+ }
+
+ static async Task ExecuteDistributedTransaction(string connectionString1, string connectionString2)
+ {
+ using (SqlConnection connection1 = new SqlConnection(connectionString1))
+ using (SqlConnection connection2 = new SqlConnection(connectionString2))
+ {
+ using (CommittableTransaction transaction = new CommittableTransaction())
+ {
+ await connection1.OpenAsync();
+ connection1.EnlistTransaction(transaction);
+
+ await connection2.OpenAsync();
+ connection2.EnlistTransaction(transaction);
+
+ try
+ {
+ SqlCommand command1 = connection1.CreateCommand();
+ command1.CommandText = "Insert into RegionTable1 (RegionID, RegionDescription) VALUES (100, 'Description')";
+ await command1.ExecuteNonQueryAsync();
+
+ SqlCommand command2 = connection2.CreateCommand();
+ command2.CommandText = "Insert into RegionTable2 (RegionID, RegionDescription) VALUES (100, 'Description')";
+ await command2.ExecuteNonQueryAsync();
+
+ transaction.Commit();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Exception Type: {0}", ex.GetType());
+ Console.WriteLine(" Message: {0}", ex.Message);
+
+ try
+ {
+ transaction.Rollback();
+ }
+ catch (Exception ex2)
+ {
+ Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
+ Console.WriteLine(" Message: {0}", ex2.Message);
+ }
+ }
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClient_AsyncProgramming_MultipleCommands.cs b/doc/samples/SqlClient_AsyncProgramming_MultipleCommands.cs
new file mode 100644
index 0000000000..6f53f2b55c
--- /dev/null
+++ b/doc/samples/SqlClient_AsyncProgramming_MultipleCommands.cs
@@ -0,0 +1,72 @@
+using System;
+//
+using System.Data.Common;
+using Microsoft.Data.SqlClient;
+using System.Threading.Tasks;
+
+class Class1
+{
+ static void Main()
+ {
+ Task task = MultipleCommands();
+ task.Wait();
+ }
+
+ static async Task MultipleCommands()
+ {
+ // By default, MARS is disabled when connecting to a MARS-enabled.
+ // It must be enabled in the connection string.
+ string connectionString = GetConnectionString();
+
+ int vendorID;
+ SqlDataReader productReader = null;
+ string vendorSQL =
+ "SELECT BusinessEntityID, Name FROM Purchasing.Vendor";
+ string productSQL =
+ "SELECT Production.Product.Name FROM Production.Product " +
+ "INNER JOIN Purchasing.ProductVendor " +
+ "ON Production.Product.ProductID = " +
+ "Purchasing.ProductVendor.ProductID " +
+ "WHERE Purchasing.ProductVendor.BusinessEntityID = @VendorId";
+
+ using (SqlConnection awConnection =
+ new SqlConnection(connectionString))
+ {
+ SqlCommand vendorCmd = new SqlCommand(vendorSQL, awConnection);
+ SqlCommand productCmd =
+ new SqlCommand(productSQL, awConnection);
+
+ productCmd.Parameters.Add("@VendorId", SqlDbType.Int);
+
+ await awConnection.OpenAsync();
+ using (SqlDataReader vendorReader = await vendorCmd.ExecuteReaderAsync())
+ {
+ while (await vendorReader.ReadAsync())
+ {
+ Console.WriteLine(vendorReader["Name"]);
+
+ vendorID = (int)vendorReader["BusinessEntityID"];
+
+ productCmd.Parameters["@VendorId"].Value = vendorID;
+ // The following line of code requires a MARS-enabled connection.
+ productReader = await productCmd.ExecuteReaderAsync();
+ using (productReader)
+ {
+ while (await productReader.ReadAsync())
+ {
+ Console.WriteLine(" " +
+ productReader["Name"].ToString());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code, you can retrieve it from a configuration file.
+ return "Data Source=(local);Integrated Security=SSPI;Initial Catalog=AdventureWorks;MultipleActiveResultSets=True";
+ }
+}
+//
diff --git a/doc/samples/SqlClient_AsyncProgramming_MultipleCommandsEx.cs b/doc/samples/SqlClient_AsyncProgramming_MultipleCommandsEx.cs
new file mode 100644
index 0000000000..47376ca18c
--- /dev/null
+++ b/doc/samples/SqlClient_AsyncProgramming_MultipleCommandsEx.cs
@@ -0,0 +1,116 @@
+using System;
+//
+using System.Data.Common;
+using Microsoft.Data.SqlClient;
+using System.Threading.Tasks;
+
+class Program
+{
+ static void Main()
+ {
+ Task task = ReadingAndUpdatingData();
+ task.Wait();
+ }
+
+ static async Task ReadingAndUpdatingData()
+ {
+ // By default, MARS is disabled when connecting to a MARS-enabled host.
+ // It must be enabled in the connection string.
+ string connectionString = GetConnectionString();
+
+ SqlTransaction updateTx = null;
+ SqlCommand vendorCmd = null;
+ SqlCommand prodVendCmd = null;
+ SqlCommand updateCmd = null;
+
+ SqlDataReader prodVendReader = null;
+
+ int vendorID = 0;
+ int productID = 0;
+ int minOrderQty = 0;
+ int maxOrderQty = 0;
+ int onOrderQty = 0;
+ int recordsUpdated = 0;
+ int totalRecordsUpdated = 0;
+
+ string vendorSQL =
+ "SELECT BusinessEntityID, Name FROM Purchasing.Vendor " +
+ "WHERE CreditRating = 5";
+ string prodVendSQL =
+ "SELECT ProductID, MaxOrderQty, MinOrderQty, OnOrderQty " +
+ "FROM Purchasing.ProductVendor " +
+ "WHERE BusinessEntityID = @VendorID";
+ string updateSQL =
+ "UPDATE Purchasing.ProductVendor " +
+ "SET OnOrderQty = @OrderQty " +
+ "WHERE ProductID = @ProductID AND BusinessEntityID = @VendorID";
+
+ using (SqlConnection awConnection =
+ new SqlConnection(connectionString))
+ {
+ await awConnection.OpenAsync();
+ updateTx = await Task.Run(() => awConnection.BeginTransaction());
+
+ vendorCmd = new SqlCommand(vendorSQL, awConnection);
+ vendorCmd.Transaction = updateTx;
+
+ prodVendCmd = new SqlCommand(prodVendSQL, awConnection);
+ prodVendCmd.Transaction = updateTx;
+ prodVendCmd.Parameters.Add("@VendorId", SqlDbType.Int);
+
+ updateCmd = new SqlCommand(updateSQL, awConnection);
+ updateCmd.Transaction = updateTx;
+ updateCmd.Parameters.Add("@OrderQty", SqlDbType.Int);
+ updateCmd.Parameters.Add("@ProductID", SqlDbType.Int);
+ updateCmd.Parameters.Add("@VendorID", SqlDbType.Int);
+
+ using (SqlDataReader vendorReader = await vendorCmd.ExecuteReaderAsync())
+ {
+ while (await vendorReader.ReadAsync())
+ {
+ Console.WriteLine(vendorReader["Name"]);
+
+ vendorID = (int)vendorReader["BusinessEntityID"];
+ prodVendCmd.Parameters["@VendorID"].Value = vendorID;
+ prodVendReader = await prodVendCmd.ExecuteReaderAsync();
+
+ using (prodVendReader)
+ {
+ while (await prodVendReader.ReadAsync())
+ {
+ productID = (int)prodVendReader["ProductID"];
+
+ if (prodVendReader["OnOrderQty"] == DBNull.Value)
+ {
+ minOrderQty = (int)prodVendReader["MinOrderQty"];
+ onOrderQty = minOrderQty;
+ }
+ else
+ {
+ maxOrderQty = (int)prodVendReader["MaxOrderQty"];
+ onOrderQty = (int)(maxOrderQty / 2);
+ }
+
+ updateCmd.Parameters["@OrderQty"].Value = onOrderQty;
+ updateCmd.Parameters["@ProductID"].Value = productID;
+ updateCmd.Parameters["@VendorID"].Value = vendorID;
+
+ recordsUpdated = await updateCmd.ExecuteNonQueryAsync();
+ totalRecordsUpdated += recordsUpdated;
+ }
+ }
+ }
+ }
+ Console.WriteLine("Total Records Updated: ", totalRecordsUpdated.ToString());
+ await Task.Run(() => updateTx.Rollback());
+ Console.WriteLine("Transaction Rolled Back");
+ }
+ }
+
+ private static string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code, you can retrieve it from a configuration file.
+ return "Data Source=(local);Integrated Security=SSPI;Initial Catalog=AdventureWorks;MultipleActiveResultSets=True";
+ }
+}
+//
diff --git a/doc/samples/SqlClient_AsyncProgramming_ProviderModel.cs b/doc/samples/SqlClient_AsyncProgramming_ProviderModel.cs
new file mode 100644
index 0000000000..7653e3947d
--- /dev/null
+++ b/doc/samples/SqlClient_AsyncProgramming_ProviderModel.cs
@@ -0,0 +1,46 @@
+using System;
+//
+using System.Data.Common;
+using Microsoft.Data.SqlClient;
+using System.Threading.Tasks;
+
+class program
+{
+ static async Task PerformDBOperationsUsingProviderModel(string connectionString)
+ {
+ using (DbConnection connection = SqlClientFactory.Instance.CreateConnection())
+ {
+ connection.ConnectionString = connectionString;
+ await connection.OpenAsync();
+
+ DbCommand command = connection.CreateCommand();
+ command.CommandText = "SELECT * FROM AUTHORS";
+
+ using (DbDataReader reader = await command.ExecuteReaderAsync())
+ {
+ while (await reader.ReadAsync())
+ {
+ for (int i = 0; i < reader.FieldCount; i++)
+ {
+ // Process each column as appropriate
+ object obj = await reader.GetFieldValueAsync
diff --git a/doc/samples/SqlClient_AsyncProgramming_SqlBulkCopy.cs b/doc/samples/SqlClient_AsyncProgramming_SqlBulkCopy.cs
new file mode 100644
index 0000000000..7a383410fc
--- /dev/null
+++ b/doc/samples/SqlClient_AsyncProgramming_SqlBulkCopy.cs
@@ -0,0 +1,275 @@
+using System;
+//
+using System.Data;
+using Microsoft.Data.SqlClient;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace SqlBulkCopyAsyncCodeSample
+{
+ class Program
+ {
+ static string selectStatement = "SELECT * FROM [pubs].[dbo].[titles]";
+ static string createDestTableStatement =
+ @"CREATE TABLE {0} (
+ [title_id] [varchar](6) NOT NULL,
+ [title] [varchar](80) NOT NULL,
+ [type] [char](12) NOT NULL,
+ [pub_id] [char](4) NULL,
+ [price] [money] NULL,
+ [advance] [money] NULL,
+ [royalty] [int] NULL,
+ [ytd_sales] [int] NULL,
+ [notes] [varchar](200) NULL,
+ [pubdate] [datetime] NOT NULL)";
+
+ // Replace the connection string if needed, for instance to connect to SQL Express: @"Server=(local)\SQLEXPRESS;Database=Demo;Integrated Security=true"
+ // static string connectionString = @"Server=(localdb)\V11.0;Database=Demo";
+ static string connectionString = @"Server=(local);Database=Demo;Integrated Security=true";
+
+ // static string marsConnectionString = @"Server=(localdb)\V11.0;Database=Demo;MultipleActiveResultSets=true;";
+ static string marsConnectionString = @"Server=(local);Database=Demo;MultipleActiveResultSets=true;Integrated Security=true";
+
+ // Replace the Server name with your actual sql azure server name and User ID/Password
+ static string azureConnectionString = @"Server=SqlAzure;User ID=;Password=;Database=Demo";
+
+ static void Main(string[] args)
+ {
+ SynchronousSqlBulkCopy();
+ AsyncSqlBulkCopy().Wait();
+ MixSyncAsyncSqlBulkCopy().Wait();
+ AsyncSqlBulkCopyNotifyAfter().Wait();
+ AsyncSqlBulkCopyDataRows().Wait();
+ AsyncSqlBulkCopySqlServerToSqlAzure().Wait();
+ AsyncSqlBulkCopyCancel().Wait();
+ AsyncSqlBulkCopyMARS().Wait();
+ }
+
+ // 3.1.1 Synchronous bulk copy in .NET 4.5
+ private static void SynchronousSqlBulkCopy()
+ {
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ conn.Open();
+ DataTable dt = new DataTable();
+ using (SqlCommand cmd = new SqlCommand(selectStatement, conn))
+ {
+ SqlDataAdapter adapter = new SqlDataAdapter(cmd);
+ adapter.Fill(dt);
+
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ cmd.CommandText = string.Format(createDestTableStatement, temptable);
+ cmd.ExecuteNonQuery();
+
+ using (SqlBulkCopy bcp = new SqlBulkCopy(conn))
+ {
+ bcp.DestinationTableName = temptable;
+ bcp.WriteToServer(dt);
+ }
+ }
+ }
+
+ }
+
+ // 3.1.2 Asynchronous bulk copy in .NET 4.5
+ private static async Task AsyncSqlBulkCopy()
+ {
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ await conn.OpenAsync();
+ DataTable dt = new DataTable();
+ using (SqlCommand cmd = new SqlCommand(selectStatement, conn))
+ {
+ SqlDataAdapter adapter = new SqlDataAdapter(cmd);
+ adapter.Fill(dt);
+
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ cmd.CommandText = string.Format(createDestTableStatement, temptable);
+ await cmd.ExecuteNonQueryAsync();
+
+ using (SqlBulkCopy bcp = new SqlBulkCopy(conn))
+ {
+ bcp.DestinationTableName = temptable;
+ await bcp.WriteToServerAsync(dt);
+ }
+ }
+ }
+ }
+
+ // 3.2 Add new Async.NET capabilities in an existing application (Mixing synchronous and asynchronous calls)
+ private static async Task MixSyncAsyncSqlBulkCopy()
+ {
+ using (SqlConnection conn1 = new SqlConnection(connectionString))
+ {
+ conn1.Open();
+ using (SqlCommand cmd = new SqlCommand(selectStatement, conn1))
+ {
+ using (SqlDataReader reader = cmd.ExecuteReader())
+ {
+ using (SqlConnection conn2 = new SqlConnection(connectionString))
+ {
+ await conn2.OpenAsync();
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ SqlCommand createCmd = new SqlCommand(string.Format(createDestTableStatement, temptable), conn2);
+ await createCmd.ExecuteNonQueryAsync();
+ using (SqlBulkCopy bcp = new SqlBulkCopy(conn2))
+ {
+ bcp.DestinationTableName = temptable;
+ await bcp.WriteToServerAsync(reader);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 3.3 Using the NotifyAfter property
+ private static async Task AsyncSqlBulkCopyNotifyAfter()
+ {
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ await conn.OpenAsync();
+ DataTable dt = new DataTable();
+ using (SqlCommand cmd = new SqlCommand(selectStatement, conn))
+ {
+ SqlDataAdapter adapter = new SqlDataAdapter(cmd);
+ adapter.Fill(dt);
+
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ cmd.CommandText = string.Format(createDestTableStatement, temptable);
+ await cmd.ExecuteNonQueryAsync();
+
+ using (SqlBulkCopy bcp = new SqlBulkCopy(conn))
+ {
+ bcp.DestinationTableName = temptable;
+ bcp.NotifyAfter = 5;
+ bcp.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnSqlRowsCopied);
+ await bcp.WriteToServerAsync(dt);
+ }
+ }
+ }
+ }
+
+ private static void OnSqlRowsCopied(object sender, SqlRowsCopiedEventArgs e)
+ {
+ Console.WriteLine("Copied {0} so far...", e.RowsCopied);
+ }
+
+ // 3.4 Using the new SqlBulkCopy Async.NET capabilities with DataRow[]
+ private static async Task AsyncSqlBulkCopyDataRows()
+ {
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ await conn.OpenAsync();
+ DataTable dt = new DataTable();
+ using (SqlCommand cmd = new SqlCommand(selectStatement, conn))
+ {
+ SqlDataAdapter adapter = new SqlDataAdapter(cmd);
+ adapter.Fill(dt);
+ DataRow[] rows = dt.Select();
+
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ cmd.CommandText = string.Format(createDestTableStatement, temptable);
+ await cmd.ExecuteNonQueryAsync();
+
+ using (SqlBulkCopy bcp = new SqlBulkCopy(conn))
+ {
+ bcp.DestinationTableName = temptable;
+ await bcp.WriteToServerAsync(rows);
+ }
+ }
+ }
+ }
+
+ // 3.5 Copying data from SQL Server to SQL Azure in .NET 4.5
+ private static async Task AsyncSqlBulkCopySqlServerToSqlAzure()
+ {
+ using (SqlConnection srcConn = new SqlConnection(connectionString))
+ using (SqlConnection destConn = new SqlConnection(azureConnectionString))
+ {
+ await srcConn.OpenAsync();
+ await destConn.OpenAsync();
+ using (SqlCommand srcCmd = new SqlCommand(selectStatement, srcConn))
+ {
+ using (SqlDataReader reader = await srcCmd.ExecuteReaderAsync())
+ {
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ using (SqlCommand destCmd = new SqlCommand(string.Format(createDestTableStatement, temptable), destConn))
+ {
+ await destCmd.ExecuteNonQueryAsync();
+ using (SqlBulkCopy bcp = new SqlBulkCopy(destConn))
+ {
+ bcp.DestinationTableName = temptable;
+ await bcp.WriteToServerAsync(reader);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 3.6 Cancelling an Asynchronous Operation to SQL Azure
+ private static async Task AsyncSqlBulkCopyCancel()
+ {
+ CancellationTokenSource cts = new CancellationTokenSource();
+ using (SqlConnection srcConn = new SqlConnection(connectionString))
+ using (SqlConnection destConn = new SqlConnection(azureConnectionString))
+ {
+ await srcConn.OpenAsync(cts.Token);
+ await destConn.OpenAsync(cts.Token);
+ using (SqlCommand srcCmd = new SqlCommand(selectStatement, srcConn))
+ {
+ using (SqlDataReader reader = await srcCmd.ExecuteReaderAsync(cts.Token))
+ {
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ using (SqlCommand destCmd = new SqlCommand(string.Format(createDestTableStatement, temptable), destConn))
+ {
+ await destCmd.ExecuteNonQueryAsync(cts.Token);
+ using (SqlBulkCopy bcp = new SqlBulkCopy(destConn))
+ {
+ bcp.DestinationTableName = temptable;
+ await bcp.WriteToServerAsync(reader, cts.Token);
+ //Cancel Async SqlBulCopy Operation after 200 ms
+ cts.CancelAfter(200);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 3.7 Using Async.Net and MARS
+ private static async Task AsyncSqlBulkCopyMARS()
+ {
+ using (SqlConnection marsConn = new SqlConnection(marsConnectionString))
+ {
+ await marsConn.OpenAsync();
+
+ SqlCommand titlesCmd = new SqlCommand("SELECT * FROM [pubs].[dbo].[titles]", marsConn);
+ SqlCommand authorsCmd = new SqlCommand("SELECT * FROM [pubs].[dbo].[authors]", marsConn);
+ //With MARS we can have multiple active results sets on the same connection
+ using (SqlDataReader titlesReader = await titlesCmd.ExecuteReaderAsync())
+ using (SqlDataReader authorsReader = await authorsCmd.ExecuteReaderAsync())
+ {
+ await authorsReader.ReadAsync();
+
+ string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
+ using (SqlConnection destConn = new SqlConnection(connectionString))
+ {
+ await destConn.OpenAsync();
+ using (SqlCommand destCmd = new SqlCommand(string.Format(createDestTableStatement, temptable), destConn))
+ {
+ await destCmd.ExecuteNonQueryAsync();
+ using (SqlBulkCopy bcp = new SqlBulkCopy(destConn))
+ {
+ bcp.DestinationTableName = temptable;
+ await bcp.WriteToServerAsync(titlesReader);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClient_AsyncProgramming_SqlTransaction.cs b/doc/samples/SqlClient_AsyncProgramming_SqlTransaction.cs
new file mode 100644
index 0000000000..86659b3c98
--- /dev/null
+++ b/doc/samples/SqlClient_AsyncProgramming_SqlTransaction.cs
@@ -0,0 +1,70 @@
+using System;
+//
+using Microsoft.Data.SqlClient;
+using System.Threading.Tasks;
+
+class Program
+{
+ static void Main()
+ {
+ string connectionString =
+ "Persist Security Info=False;Integrated Security=SSPI;database=Northwind;server=(local)";
+ Task task = ExecuteSqlTransaction(connectionString);
+ task.Wait();
+ }
+
+ static async Task ExecuteSqlTransaction(string connectionString)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ await connection.OpenAsync();
+
+ SqlCommand command = connection.CreateCommand();
+ SqlTransaction transaction = null;
+
+ // Start a local transaction.
+ transaction = await Task.Run(
+ () => connection.BeginTransaction("SampleTransaction")
+ );
+
+ // Must assign both transaction object and connection
+ // to Command object for a pending local transaction
+ command.Connection = connection;
+ command.Transaction = transaction;
+
+ try {
+ command.CommandText =
+ "Insert into Region (RegionID, RegionDescription) VALUES (555, 'Description')";
+ await command.ExecuteNonQueryAsync();
+
+ command.CommandText =
+ "Insert into Region (RegionID, RegionDescription) VALUES (556, 'Description')";
+ await command.ExecuteNonQueryAsync();
+
+ // Attempt to commit the transaction.
+ await Task.Run(() => transaction.Commit());
+ Console.WriteLine("Both records are written to database.");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
+ Console.WriteLine(" Message: {0}", ex.Message);
+
+ // Attempt to roll back the transaction.
+ try
+ {
+ transaction.Rollback();
+ }
+ catch (Exception ex2)
+ {
+ // This catch block will handle any errors that may have occurred
+ // on the server that would cause the rollback to fail, such as
+ // a closed connection.
+ Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
+ Console.WriteLine(" Message: {0}", ex2.Message);
+ }
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClient_PerformanceCounter.cs b/doc/samples/SqlClient_PerformanceCounter.cs
new file mode 100644
index 0000000000..e015d6f6b1
--- /dev/null
+++ b/doc/samples/SqlClient_PerformanceCounter.cs
@@ -0,0 +1,173 @@
+//
+using System;
+using Microsoft.Data.SqlClient;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace PerformanceCounterTest
+{
+ class Program
+ {
+ PerformanceCounter[] PerfCounters = new PerformanceCounter[10];
+ SqlConnection connection = new SqlConnection();
+
+ static void Main()
+ {
+ Program prog = new Program();
+ // Open a connection and create the performance counters.
+ prog.connection.ConnectionString =
+ GetIntegratedSecurityConnectionString();
+ prog.SetUpPerformanceCounters();
+ Console.WriteLine("Available Performance Counters:");
+
+ // Create the connections and display the results.
+ prog.CreateConnections();
+ Console.WriteLine("Press Enter to finish.");
+ Console.ReadLine();
+ }
+
+ private void CreateConnections()
+ {
+ // List the Performance counters.
+ WritePerformanceCounters();
+
+ // Create 4 connections and display counter information.
+ SqlConnection connection1 = new SqlConnection(
+ GetIntegratedSecurityConnectionString());
+ connection1.Open();
+ Console.WriteLine("Opened the 1st Connection:");
+ WritePerformanceCounters();
+
+ SqlConnection connection2 = new SqlConnection(
+ GetSqlConnectionStringDifferent());
+ connection2.Open();
+ Console.WriteLine("Opened the 2nd Connection:");
+ WritePerformanceCounters();
+
+ SqlConnection connection3 = new SqlConnection(
+ GetSqlConnectionString());
+ connection3.Open();
+ Console.WriteLine("Opened the 3rd Connection:");
+ WritePerformanceCounters();
+
+ SqlConnection connection4 = new SqlConnection(
+ GetSqlConnectionString());
+ connection4.Open();
+ Console.WriteLine("Opened the 4th Connection:");
+ WritePerformanceCounters();
+
+ connection1.Close();
+ Console.WriteLine("Closed the 1st Connection:");
+ WritePerformanceCounters();
+
+ connection2.Close();
+ Console.WriteLine("Closed the 2nd Connection:");
+ WritePerformanceCounters();
+
+ connection3.Close();
+ Console.WriteLine("Closed the 3rd Connection:");
+ WritePerformanceCounters();
+
+ connection4.Close();
+ Console.WriteLine("Closed the 4th Connection:");
+ WritePerformanceCounters();
+ }
+
+ private enum ADO_Net_Performance_Counters
+ {
+ NumberOfActiveConnectionPools,
+ NumberOfReclaimedConnections,
+ HardConnectsPerSecond,
+ HardDisconnectsPerSecond,
+ NumberOfActiveConnectionPoolGroups,
+ NumberOfInactiveConnectionPoolGroups,
+ NumberOfInactiveConnectionPools,
+ NumberOfNonPooledConnections,
+ NumberOfPooledConnections,
+ NumberOfStasisConnections
+ // The following performance counters are more expensive to track.
+ // Enable ConnectionPoolPerformanceCounterDetail in your config file.
+ // SoftConnectsPerSecond
+ // SoftDisconnectsPerSecond
+ // NumberOfActiveConnections
+ // NumberOfFreeConnections
+ }
+
+ private void SetUpPerformanceCounters()
+ {
+ connection.Close();
+ this.PerfCounters = new PerformanceCounter[10];
+ string instanceName = GetInstanceName();
+ Type apc = typeof(ADO_Net_Performance_Counters);
+ int i = 0;
+ foreach (string s in Enum.GetNames(apc))
+ {
+ this.PerfCounters[i] = new PerformanceCounter();
+ this.PerfCounters[i].CategoryName = ".NET Data Provider for SqlServer";
+ this.PerfCounters[i].CounterName = s;
+ this.PerfCounters[i].InstanceName = instanceName;
+ i++;
+ }
+ }
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern int GetCurrentProcessId();
+
+ private string GetInstanceName()
+ {
+ //This works for Winforms apps.
+ string instanceName =
+ System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
+
+ // Must replace special characters like (, ), #, /, \\
+ string instanceName2 =
+ AppDomain.CurrentDomain.FriendlyName.ToString().Replace('(', '[')
+ .Replace(')', ']').Replace('#', '_').Replace('/', '_').Replace('\\', '_');
+
+ // For ASP.NET applications your instanceName will be your CurrentDomain's
+ // FriendlyName. Replace the line above that sets the instanceName with this:
+ // instanceName = AppDomain.CurrentDomain.FriendlyName.ToString().Replace('(','[')
+ // .Replace(')',']').Replace('#','_').Replace('/','_').Replace('\\','_');
+
+ string pid = GetCurrentProcessId().ToString();
+ instanceName = instanceName + "[" + pid + "]";
+ Console.WriteLine("Instance Name: {0}", instanceName);
+ Console.WriteLine("---------------------------");
+ return instanceName;
+ }
+
+ private void WritePerformanceCounters()
+ {
+ Console.WriteLine("---------------------------");
+ foreach (PerformanceCounter p in this.PerfCounters)
+ {
+ Console.WriteLine("{0} = {1}", p.CounterName, p.NextValue());
+ }
+ Console.WriteLine("---------------------------");
+ }
+
+ private static string GetIntegratedSecurityConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return @"Data Source=.;Integrated Security=True;" +
+ "Initial Catalog=AdventureWorks";
+ }
+ private static string GetSqlConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return @"Data Source=.;User Id=;Password=;" +
+ "Initial Catalog=AdventureWorks";
+ }
+
+ private static string GetSqlConnectionStringDifferent()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return @"Initial Catalog=AdventureWorks;Data Source=.;" +
+ "User Id=;Password=;";
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClient_RetrieveIdentity.cs b/doc/samples/SqlClient_RetrieveIdentity.cs
new file mode 100644
index 0000000000..ba08be607a
--- /dev/null
+++ b/doc/samples/SqlClient_RetrieveIdentity.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+namespace AutoNumberTest
+{
+ class Program
+ {
+ //
+ static void Main(string[] args)
+ {
+ String SqlDbConnectionString = "Data Source=(local);Initial Catalog=MySchool;Integrated Security=True;";
+
+ InsertPersonInCommand(SqlDbConnectionString, "Janice", "Galvin");
+ Console.WriteLine();
+
+ InsertPersonInAdapter(SqlDbConnectionString, "Peter", "Krebs");
+ Console.WriteLine();
+
+ Console.WriteLine("Please press any key to exit.....");
+ Console.ReadKey();
+ }
+
+ // Using stored procedure to insert a new row and retrieve the identity value
+ static void InsertPersonInCommand(String connectionString, String firstName, String lastName)
+ {
+ String commandText = "dbo.InsertPerson";
+
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ using (SqlCommand cmd = new SqlCommand(commandText, conn))
+ {
+ cmd.CommandType = CommandType.StoredProcedure;
+
+ cmd.Parameters.Add(new SqlParameter("@FirstName", firstName));
+ cmd.Parameters.Add(new SqlParameter("@LastName", lastName));
+ SqlParameter personId = new SqlParameter("@PersonID", SqlDbType.Int);
+ personId.Direction = ParameterDirection.Output;
+ cmd.Parameters.Add(personId);
+
+ conn.Open();
+ cmd.ExecuteNonQuery();
+
+ Console.WriteLine("Person Id of new person:{0}", personId.Value);
+ }
+ }
+ }
+
+ // Using stored procedure in adapter to insert new rows and update the identity value.
+ static void InsertPersonInAdapter(String connectionString, String firstName, String lastName)
+ {
+ String commandText = "dbo.InsertPerson";
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ SqlDataAdapter mySchool = new SqlDataAdapter("Select PersonID,FirstName,LastName from [dbo].[Person]", conn);
+
+ mySchool.InsertCommand = new SqlCommand(commandText, conn);
+ mySchool.InsertCommand.CommandType = CommandType.StoredProcedure;
+
+ mySchool.InsertCommand.Parameters.Add(
+ new SqlParameter("@FirstName", SqlDbType.NVarChar, 50, "FirstName"));
+ mySchool.InsertCommand.Parameters.Add(
+ new SqlParameter("@LastName", SqlDbType.NVarChar, 50, "LastName"));
+
+ SqlParameter personId = mySchool.InsertCommand.Parameters.Add(new SqlParameter("@PersonID", SqlDbType.Int, 0, "PersonID"));
+ personId.Direction = ParameterDirection.Output;
+
+ DataTable persons = new DataTable();
+ mySchool.Fill(persons);
+
+ DataRow newPerson = persons.NewRow();
+ newPerson["FirstName"] = firstName;
+ newPerson["LastName"] = lastName;
+ persons.Rows.Add(newPerson);
+
+ mySchool.Update(persons);
+ Console.WriteLine("Show all persons:");
+ ShowDataTable(persons, 14);
+ }
+ }
+
+ private static void ShowDataTable(DataTable table, Int32 length)
+ {
+ foreach (DataColumn col in table.Columns)
+ {
+ Console.Write("{0,-" + length + "}", col.ColumnName);
+ }
+ Console.WriteLine();
+
+ foreach (DataRow row in table.Rows)
+ {
+ foreach (DataColumn col in table.Columns)
+ {
+ if (col.DataType.Equals(typeof(DateTime)))
+ Console.Write("{0,-" + length + ":d}", row[col]);
+ else if (col.DataType.Equals(typeof(Decimal)))
+ Console.Write("{0,-" + length + ":C}", row[col]);
+ else
+ Console.Write("{0,-" + length + "}", row[col]);
+ }
+
+ Console.WriteLine();
+ }
+ }
+ //
+ }
+}
diff --git a/doc/samples/SqlClient_Streaming_FromServer.cs b/doc/samples/SqlClient_Streaming_FromServer.cs
new file mode 100644
index 0000000000..a139b828e6
--- /dev/null
+++ b/doc/samples/SqlClient_Streaming_FromServer.cs
@@ -0,0 +1,226 @@
+//
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+using System.IO;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace StreamingFromServer
+{
+ class Program
+ {
+ private const string connectionString = @"Server=localhost;Database=Demo;Integrated Security=true";
+
+ static void Main(string[] args)
+ {
+ CopyBinaryValueToFile().Wait();
+ PrintTextValues().Wait();
+ PrintXmlValues().Wait();
+ PrintXmlValuesViaNVarChar().Wait();
+
+ Console.WriteLine("Done");
+ }
+
+ // Application retrieving a large BLOB from SQL Server in .NET 4.5 using the new asynchronous capability
+ private static async Task CopyBinaryValueToFile()
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ await connection.OpenAsync();
+ using (SqlCommand command = new SqlCommand("SELECT [bindata] FROM [Streams] WHERE [id]=@id", connection))
+ {
+ command.Parameters.AddWithValue("id", 1);
+
+ // The reader needs to be executed with the SequentialAccess behavior to enable network streaming
+ // Otherwise ReadAsync will buffer the entire BLOB into memory which can cause scalability issues or even OutOfMemoryExceptions
+ using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
+ {
+ if (await reader.ReadAsync())
+ {
+ if (!(await reader.IsDBNullAsync(0)))
+ {
+ using (FileStream file = new FileStream("binarydata.bin", FileMode.Create, FileAccess.Write))
+ {
+ using (Stream data = reader.GetStream(0))
+ {
+
+ // Asynchronously copy the stream from the server to the file we just created
+ await data.CopyToAsync(file);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Application transferring a large Text File from SQL Server
+ private static async Task PrintTextValues()
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ await connection.OpenAsync();
+ using (SqlCommand command = new SqlCommand("SELECT [id], [textdata] FROM [Streams]", connection))
+ {
+
+ // The reader needs to be executed with the SequentialAccess behavior to enable network streaming
+ // Otherwise ReadAsync will buffer the entire text document into memory which can cause scalability issues or even OutOfMemoryExceptions
+ using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
+ {
+ while (await reader.ReadAsync())
+ {
+ Console.Write("{0}: ", reader.GetInt32(0));
+
+ if (await reader.IsDBNullAsync(1))
+ {
+ Console.Write("(NULL)");
+ }
+ else
+ {
+ char[] buffer = new char[4096];
+ int charsRead = 0;
+ using (TextReader data = reader.GetTextReader(1))
+ {
+ do
+ {
+ // Grab each chunk of text and write it to the console
+ // If you are writing to a TextWriter you should use WriteAsync or WriteLineAsync
+ charsRead = await data.ReadAsync(buffer, 0, buffer.Length);
+ Console.Write(buffer, 0, charsRead);
+ } while (charsRead > 0);
+ }
+ }
+
+ Console.WriteLine();
+ }
+ }
+ }
+ }
+ }
+
+ // Application transferring a large Xml Document from SQL Server
+ private static async Task PrintXmlValues()
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ await connection.OpenAsync();
+ using (SqlCommand command = new SqlCommand("SELECT [id], [xmldata] FROM [Streams]", connection))
+ {
+
+ // The reader needs to be executed with the SequentialAccess behavior to enable network streaming
+ // Otherwise ReadAsync will buffer the entire Xml Document into memory which can cause scalability issues or even OutOfMemoryExceptions
+ using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
+ {
+ while (await reader.ReadAsync())
+ {
+ Console.WriteLine("{0}: ", reader.GetInt32(0));
+
+ if (await reader.IsDBNullAsync(1))
+ {
+ Console.WriteLine("\t(NULL)");
+ }
+ else
+ {
+ using (XmlReader xmlReader = reader.GetXmlReader(1))
+ {
+ int depth = 1;
+ // NOTE: The XmlReader returned by GetXmlReader does NOT support async operations
+ // See the example below (PrintXmlValuesViaNVarChar) for how to get an XmlReader with asynchronous capabilities
+ while (xmlReader.Read())
+ {
+ switch (xmlReader.NodeType)
+ {
+ case XmlNodeType.Element:
+ Console.WriteLine("{0}<{1}>", new string('\t', depth), xmlReader.Name);
+ depth++;
+ break;
+ case XmlNodeType.Text:
+ Console.WriteLine("{0}{1}", new string('\t', depth), xmlReader.Value);
+ break;
+ case XmlNodeType.EndElement:
+ depth--;
+ Console.WriteLine("{0}{1}>", new string('\t', depth), xmlReader.Name);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Application transferring a large Xml Document from SQL Server
+ // This goes via NVarChar and TextReader to enable asynchronous reading
+ private static async Task PrintXmlValuesViaNVarChar()
+ {
+ XmlReaderSettings xmlSettings = new XmlReaderSettings()
+ {
+ // Async must be explicitly enabled in the XmlReaderSettings otherwise the XmlReader will throw exceptions when async methods are called
+ Async = true,
+ // Since we will immediately wrap the TextReader we are creating in an XmlReader, we will permit the XmlReader to take care of closing\disposing it
+ CloseInput = true,
+ // If the Xml you are reading is not a valid document (as per ) you will need to set the conformance level to Fragment
+ ConformanceLevel = ConformanceLevel.Fragment
+ };
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ await connection.OpenAsync();
+
+ // Cast the XML into NVarChar to enable GetTextReader - trying to use GetTextReader on an XML type will throw an exception
+ using (SqlCommand command = new SqlCommand("SELECT [id], CAST([xmldata] AS NVARCHAR(MAX)) FROM [Streams]", connection))
+ {
+
+ // The reader needs to be executed with the SequentialAccess behavior to enable network streaming
+ // Otherwise ReadAsync will buffer the entire Xml Document into memory which can cause scalability issues or even OutOfMemoryExceptions
+ using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
+ {
+ while (await reader.ReadAsync())
+ {
+ Console.WriteLine("{0}:", reader.GetInt32(0));
+
+ if (await reader.IsDBNullAsync(1))
+ {
+ Console.WriteLine("\t(NULL)");
+ }
+ else
+ {
+ // Grab the row as a TextReader, then create an XmlReader on top of it
+ // We are not keeping a reference to the TextReader since the XmlReader is created with the "CloseInput" setting (so it will close the TextReader when needed)
+ using (XmlReader xmlReader = XmlReader.Create(reader.GetTextReader(1), xmlSettings))
+ {
+ int depth = 1;
+ // The XmlReader above now supports asynchronous operations, so we can use ReadAsync here
+ while (await xmlReader.ReadAsync())
+ {
+ switch (xmlReader.NodeType)
+ {
+ case XmlNodeType.Element:
+ Console.WriteLine("{0}<{1}>", new string('\t', depth), xmlReader.Name);
+ depth++;
+ break;
+ case XmlNodeType.Text:
+ // Depending on what your data looks like, you should either use Value or GetValueAsync
+ // Value has less overhead (since it doesn't create a Task), but it may also block if additional data is required
+ Console.WriteLine("{0}{1}", new string('\t', depth), await xmlReader.GetValueAsync());
+ break;
+ case XmlNodeType.EndElement:
+ depth--;
+ Console.WriteLine("{0}{1}>", new string('\t', depth), xmlReader.Name);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClient_Streaming_ServerToServer.cs b/doc/samples/SqlClient_Streaming_ServerToServer.cs
new file mode 100644
index 0000000000..42efe6fa32
--- /dev/null
+++ b/doc/samples/SqlClient_Streaming_ServerToServer.cs
@@ -0,0 +1,72 @@
+//
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace StreamingFromServerToAnother
+{
+ class Program
+ {
+ private const string connectionString = @"Server=localhost;Database=Demo2;Integrated Security=true";
+
+ static void Main(string[] args)
+ {
+ // For this example, we don't want to cancel
+ // So we can pass in a "blank" cancellation token
+ E2EStream(CancellationToken.None).Wait();
+
+ Console.WriteLine("Done");
+ }
+
+ // Streaming from one SQL Server to Another One
+ private static async Task E2EStream(CancellationToken cancellationToken)
+ {
+ using (SqlConnection readConn = new SqlConnection(connectionString))
+ {
+ using (SqlConnection writeConn = new SqlConnection(connectionString))
+ {
+
+ // Note that we are using the same cancellation token for calls to both connections\commands
+ // Also we can start both the connection opening asynchronously, and then wait for both to complete
+ Task openReadConn = readConn.OpenAsync(cancellationToken);
+ Task openWriteConn = writeConn.OpenAsync(cancellationToken);
+ await Task.WhenAll(openReadConn, openWriteConn);
+
+ using (SqlCommand readCmd = new SqlCommand("SELECT [bindata] FROM [BinaryStreams]", readConn))
+ {
+ using (SqlCommand writeCmd = new SqlCommand("INSERT INTO [BinaryStreamsCopy] (bindata) VALUES (@bindata)", writeConn))
+ {
+
+ // Add an empty parameter to the write command which will be used for the streams we are copying
+ // Size is set to -1 to indicate "MAX"
+ SqlParameter streamParameter = writeCmd.Parameters.Add("@bindata", SqlDbType.Binary, -1);
+
+ // The reader needs to be executed with the SequentialAccess behavior to enable network streaming
+ // Otherwise ReadAsync will buffer the entire BLOB into memory which can cause scalability issues or even OutOfMemoryExceptions
+ using (SqlDataReader reader = await readCmd.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken))
+ {
+ while (await reader.ReadAsync(cancellationToken))
+ {
+ // Grab a stream to the binary data in the source database
+ using (Stream dataStream = reader.GetStream(0))
+ {
+
+ // Set the parameter value to the stream source that was opened
+ streamParameter.Value = dataStream;
+
+ // Asynchronously send data from one database to another
+ await writeCmd.ExecuteNonQueryAsync(cancellationToken);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlClient_Streaming_ToServer.cs b/doc/samples/SqlClient_Streaming_ToServer.cs
new file mode 100644
index 0000000000..6ee858db1c
--- /dev/null
+++ b/doc/samples/SqlClient_Streaming_ToServer.cs
@@ -0,0 +1,140 @@
+//
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace StreamingToServer
+{
+ class Program
+ {
+ private const string connectionString = @"Server=localhost;Database=Demo2;Integrated Security=true";
+
+ static void Main(string[] args)
+ {
+ CreateDemoFiles();
+
+ StreamBLOBToServer().Wait();
+ StreamTextToServer().Wait();
+
+ // Create a CancellationTokenSource that will be cancelled after 100ms
+ // Typically this token source will be cancelled by a user request (e.g. a Cancel button)
+ CancellationTokenSource tokenSource = new CancellationTokenSource();
+ tokenSource.CancelAfter(100);
+ try
+ {
+ CancelBLOBStream(tokenSource.Token).Wait();
+ }
+ catch (AggregateException ex)
+ {
+ // Cancelling an async operation will throw an exception
+ // Since we are using the Task's Wait method, this exception will be wrapped in an AggregateException
+ // If you were using the 'await' keyword, the compiler would take care of unwrapping the AggregateException
+ // Depending on when the cancellation occurs, you can either get an error from SQL Server or from .Net
+ if ((ex.InnerException is SqlException) || (ex.InnerException is TaskCanceledException))
+ {
+ // This is an expected exception
+ Console.WriteLine("Got expected exception: {0}", ex.InnerException.Message);
+ }
+ else
+ {
+ // Did not expect this exception - re-throw it
+ throw;
+ }
+ }
+
+ Console.WriteLine("Done");
+ }
+
+ // This is used to generate the files which are used by the other sample methods
+ private static void CreateDemoFiles()
+ {
+ Random rand = new Random();
+ byte[] data = new byte[1024];
+ rand.NextBytes(data);
+
+ using (FileStream file = File.Open("binarydata.bin", FileMode.Create))
+ {
+ file.Write(data, 0, data.Length);
+ }
+
+ using (StreamWriter writer = new StreamWriter(File.Open("textdata.txt", FileMode.Create)))
+ {
+ writer.Write(Convert.ToBase64String(data));
+ }
+ }
+
+ // Application transferring a large BLOB to SQL Server
+ private static async Task StreamBLOBToServer()
+ {
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ await conn.OpenAsync();
+ using (SqlCommand cmd = new SqlCommand("INSERT INTO [BinaryStreams] (bindata) VALUES (@bindata)", conn))
+ {
+ using (FileStream file = File.Open("binarydata.bin", FileMode.Open))
+ {
+
+ // Add a parameter which uses the FileStream we just opened
+ // Size is set to -1 to indicate "MAX"
+ cmd.Parameters.Add("@bindata", SqlDbType.Binary, -1).Value = file;
+
+ // Send the data to the server asynchronously
+ await cmd.ExecuteNonQueryAsync();
+ }
+ }
+ }
+ }
+
+ // Application transferring a large Text File to SQL Server
+ private static async Task StreamTextToServer()
+ {
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ await conn.OpenAsync();
+ using (SqlCommand cmd = new SqlCommand("INSERT INTO [TextStreams] (textdata) VALUES (@textdata)", conn))
+ {
+ using (StreamReader file = File.OpenText("textdata.txt"))
+ {
+
+ // Add a parameter which uses the StreamReader we just opened
+ // Size is set to -1 to indicate "MAX"
+ cmd.Parameters.Add("@textdata", SqlDbType.NVarChar, -1).Value = file;
+
+ // Send the data to the server asynchronously
+ await cmd.ExecuteNonQueryAsync();
+ }
+ }
+ }
+ }
+
+ // Cancelling the transfer of a large BLOB
+ private static async Task CancelBLOBStream(CancellationToken cancellationToken)
+ {
+ using (SqlConnection conn = new SqlConnection(connectionString))
+ {
+ // We can cancel not only sending the data to the server, but also opening the connection
+ await conn.OpenAsync(cancellationToken);
+
+ // Artificially delay the command by 100ms
+ using (SqlCommand cmd = new SqlCommand("WAITFOR DELAY '00:00:00:100';INSERT INTO [BinaryStreams] (bindata) VALUES (@bindata)", conn))
+ {
+ using (FileStream file = File.Open("binarydata.bin", FileMode.Open))
+ {
+
+ // Add a parameter which uses the FileStream we just opened
+ // Size is set to -1 to indicate "MAX"
+ cmd.Parameters.Add("@bindata", SqlDbType.Binary, -1).Value = file;
+
+ // Send the data to the server asynchronously
+ // Pass the cancellation token such that the command will be cancelled if needed
+ await cmd.ExecuteNonQueryAsync(cancellationToken);
+ }
+ }
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlCommandBuilder_Create.cs b/doc/samples/SqlCommandBuilder_Create.cs
new file mode 100644
index 0000000000..13322368af
--- /dev/null
+++ b/doc/samples/SqlCommandBuilder_Create.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+namespace SqlCommandBuilderCS
+{
+ class Program
+ {
+ static void Main()
+ {
+ string cnnst = "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ string queryst = "SELECT CustomerID, CompanyName, ContactName, Phone FROM Customers";
+ string newQueryString = "SELECT CustomerID, City, Region FROM Customers";
+ string tablen = "Customers";
+ DataSet ds = SelectSqlRows(cnnst, queryst, newQueryString, tablen);
+ }
+
+ public static DataSet SelectSqlRows(string connectionString,
+ string queryString, string newQueryString, string tableName)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object
+ // inside of a using block.
+ SqlDataAdapter adapter = new SqlDataAdapter();
+ adapter.SelectCommand = new SqlCommand(queryString, connection);
+ SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
+ builder.QuotePrefix = "[";
+ builder.QuoteSuffix = "]";
+ //
+
+ //
+ // Generate the update command automatically by SqlCommandBuilder
+ Console.WriteLine(builder.GetUpdateCommand().CommandText);
+ //
+
+ connection.Open();
+
+ DataSet dataSet = new DataSet();
+ adapter.Fill(dataSet, tableName);
+
+ //
+ // Assumes an open SqlConnection and SqlDataAdapter inside of a using block.
+ adapter.SelectCommand.CommandText = newQueryString;
+ builder.RefreshSchema();
+
+ dataSet.Tables.Remove(dataSet.Tables[tableName]);
+ adapter.Fill(dataSet, tableName);
+ //
+
+ //code to modify data in DataSet here
+ builder.GetUpdateCommand();
+
+ //Without the SqlCommandBuilder this line would fail
+ adapter.Update(dataSet, tableName);
+
+ return dataSet;
+ }
+ }
+ }
+}
diff --git a/doc/samples/SqlCommand_BeginExecuteNonQuery.cs b/doc/samples/SqlCommand_BeginExecuteNonQuery.cs
index 4598ffcd38..7cae30238f 100644
--- a/doc/samples/SqlCommand_BeginExecuteNonQuery.cs
+++ b/doc/samples/SqlCommand_BeginExecuteNonQuery.cs
@@ -75,11 +75,8 @@ private static string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
- // If you have not included "Asynchronous Processing=true" in the
- // connection string, the command is not able
- // to execute asynchronously.
return "Data Source=(local);Integrated Security=SSPI;" +
- "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
+ "Initial Catalog=AdventureWorks";
}
}
//
diff --git a/doc/samples/SqlCommand_BeginExecuteNonQueryForm.cs b/doc/samples/SqlCommand_BeginExecuteNonQueryForm.cs
index 5bc740978a..d800ebde16 100644
--- a/doc/samples/SqlCommand_BeginExecuteNonQueryForm.cs
+++ b/doc/samples/SqlCommand_BeginExecuteNonQueryForm.cs
@@ -49,11 +49,8 @@ private static string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
- // If you have not included "Asynchronous Processing=true" in the
- // connection string, the command is not able
- // to execute asynchronously.
return "Data Source=(local);Integrated Security=true;" +
- "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
+ "Initial Catalog=AdventureWorks";
}
private void DisplayStatus(string Text)
diff --git a/doc/samples/SqlCommand_BeginExecuteReaderAsyncBehavior.cs b/doc/samples/SqlCommand_BeginExecuteReaderAsyncBehavior.cs
index 830bf36be7..a79254fbbc 100644
--- a/doc/samples/SqlCommand_BeginExecuteReaderAsyncBehavior.cs
+++ b/doc/samples/SqlCommand_BeginExecuteReaderAsyncBehavior.cs
@@ -119,10 +119,8 @@ private string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
- // If you do not include the Asynchronous Processing=true name/value pair,
- // you wo not be able to execute the command asynchronously.
return "Data Source=(local);Integrated Security=true;" +
- "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
+ "Initial Catalog=AdventureWorks";
}
private void button1_Click(object sender, System.EventArgs e)
diff --git a/doc/samples/SqlCommand_BeginExecuteReaderAsyncSimple.cs b/doc/samples/SqlCommand_BeginExecuteReaderAsyncSimple.cs
index c010b16c06..2c5d74a8f4 100644
--- a/doc/samples/SqlCommand_BeginExecuteReaderAsyncSimple.cs
+++ b/doc/samples/SqlCommand_BeginExecuteReaderAsyncSimple.cs
@@ -92,11 +92,8 @@ private static string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
- // If you have not included "Asynchronous Processing=true" in the
- // connection string, the command is not able
- // to execute asynchronously.
return "Data Source=(local);Integrated Security=true;" +
- "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
+ "Initial Catalog=AdventureWorks";
}
}
//
diff --git a/doc/samples/SqlCommand_BeginExecuteXmlReader.cs b/doc/samples/SqlCommand_BeginExecuteXmlReader.cs
index 9f99c070a9..6935d7d117 100644
--- a/doc/samples/SqlCommand_BeginExecuteXmlReader.cs
+++ b/doc/samples/SqlCommand_BeginExecuteXmlReader.cs
@@ -75,11 +75,8 @@ private static string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
- // If you have not included "Asynchronous Processing=true" in the
- // connection string, the command is not able
- // to execute asynchronously.
return "Data Source=(local);Integrated Security=true;" +
- "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
+ "Initial Catalog=AdventureWorks";
}
}
//
diff --git a/doc/samples/SqlCommand_BeginExecuteXmlReaderAsync.cs b/doc/samples/SqlCommand_BeginExecuteXmlReaderAsync.cs
index b3ba1902ae..35195c95a7 100644
--- a/doc/samples/SqlCommand_BeginExecuteXmlReaderAsync.cs
+++ b/doc/samples/SqlCommand_BeginExecuteXmlReaderAsync.cs
@@ -37,10 +37,8 @@ private string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
- // If you do not include the Asynchronous Processing=true name/value pair,
- // you wo not be able to execute the command asynchronously.
return "Data Source=(local);Integrated Security=true;" +
- "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
+ "Initial Catalog=AdventureWorks";
}
private void DisplayStatus(string Text)
diff --git a/doc/samples/SqlCommand_ExecuteNonQueryAsync.cs b/doc/samples/SqlCommand_ExecuteNonQueryAsync.cs
new file mode 100644
index 0000000000..d1f8fc5db8
--- /dev/null
+++ b/doc/samples/SqlCommand_ExecuteNonQueryAsync.cs
@@ -0,0 +1,27 @@
+using System;
+//
+using Microsoft.Data.SqlClient;
+using System.Threading.Tasks;
+
+class A {
+ public static void Main()
+ {
+ using (SqlConnection conn = new SqlConnection("Data Source=(local); Initial Catalog=NorthWind; Integrated Security=SSPI"))
+ {
+ SqlCommand command = new SqlCommand("SELECT TOP 2 * FROM dbo.Orders", conn);
+
+ int result = A.Method(conn, command).Result;
+
+ SqlDataReader reader = command.ExecuteReader();
+ while (reader.Read())
+ Console.WriteLine(reader[0]);
+ }
+ }
+
+ static async Task Method(SqlConnection conn, SqlCommand cmd) {
+ await conn.OpenAsync();
+ await cmd.ExecuteNonQueryAsync();
+ return 1;
+ }
+}
+//
diff --git a/doc/samples/SqlCommand_ExecuteNonQuery_SP_DML.cs b/doc/samples/SqlCommand_ExecuteNonQuery_SP_DML.cs
new file mode 100644
index 0000000000..6b35ce142b
--- /dev/null
+++ b/doc/samples/SqlCommand_ExecuteNonQuery_SP_DML.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+namespace SqlCommandCS
+{
+ class Program
+ {
+ static void Main()
+ {
+ string str = "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+
+ CreateStoredProcedure(str);
+ CreateCommand(str);
+ }
+
+ private static void CreateStoredProcedure(string connectionString)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ //
+ // Assumes connection is a valid SqlConnection.
+ string queryString = "CREATE PROCEDURE InsertCategory " +
+ "@CategoryName nchar(15), " +
+ "@Identity int OUT " +
+ "AS " +
+ "INSERT INTO Categories (CategoryName) VALUES(@CategoryName) " +
+ "SET @Identity = @@Identity " +
+ "RETURN @@ROWCOUNT";
+
+ SqlCommand command = new SqlCommand(queryString, connection);
+ command.ExecuteNonQuery();
+ //
+ }
+ }
+
+ private static void CreateCommand(string connectionString)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ SqlCommand command = new SqlCommand(connection);
+
+ //
+ // Assumes connection is a valid SqlConnection.
+ connection.Open();
+
+ string queryString = "INSERT INTO Customers " +
+ "(CustomerID, CompanyName) Values('NWIND', 'Northwind Traders')";
+
+ SqlCommand command = new SqlCommand(queryString, connection);
+ Int32 recordsAffected = command.ExecuteNonQuery();
+ //
+
+ //
+ // Assumes command is a valid SqlCommand with an open connection.
+ command.CommandText = "InsertCategory";
+ command.CommandType = CommandType.StoredProcedure;
+
+ SqlParameter parameter = command.Parameters.Add("@RowCount", SqlDbType.Int);
+ parameter.Direction = ParameterDirection.ReturnValue;
+
+ parameter = command.Parameters.Add("@CategoryName", SqlDbType.NChar, 15);
+
+ parameter = command.Parameters.Add("@Identity", SqlDbType.Int);
+ parameter.Direction = ParameterDirection.Output;
+
+ command.Parameters["@CategoryName"].Value = "New Category";
+ command.ExecuteNonQuery();
+
+ Int32 categoryID = (Int32) command.Parameters["@Identity"].Value;
+ Int32 rowCount = (Int32) command.Parameters["@RowCount"].Value;
+ //
+ }
+ }
+ }
+}
diff --git a/doc/samples/SqlCommand_ExecuteReader_SequentialAccess.cs b/doc/samples/SqlCommand_ExecuteReader_SequentialAccess.cs
new file mode 100644
index 0000000000..864e183428
--- /dev/null
+++ b/doc/samples/SqlCommand_ExecuteReader_SequentialAccess.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main()
+ {
+ string cnnString = "Data Source=(local);Initial Catalog=pubs;"
+ + "Integrated Security=SSPI";
+ SqlConnection connection = new SqlConnection(cnnString);
+ RetrievePubLogo(connection);
+ }
+
+ private static void RetrievePubLogo(SqlConnection connection)
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object.
+ SqlCommand command = new SqlCommand(
+ "SELECT pub_id, logo FROM pub_info", connection);
+
+ // Writes the BLOB to a file (*.bmp).
+ System.IO.FileStream stream;
+ // Streams the BLOB to the FileStream object.
+ System.IO.BinaryWriter writer;
+
+ // Size of the BLOB buffer.
+ int bufferSize = 100;
+ // The BLOB byte[] buffer to be filled by GetBytes.
+ byte[] outByte = new byte[bufferSize];
+ // The bytes returned from GetBytes.
+ long retval;
+ // The starting position in the BLOB output.
+ long startIndex = 0;
+
+ // The publisher id to use in the file name.
+ string pubID = "";
+
+ // Open the connection and read data into the DataReader.
+ connection.Open();
+ SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
+
+ while (reader.Read())
+ {
+ // Get the publisher id, which must occur before getting the logo.
+ pubID = reader.GetString(0);
+
+ // Create a file to hold the output.
+ stream = new System.IO.FileStream(
+ "logo" + pubID + ".bmp", System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write);
+ writer = new System.IO.BinaryWriter(stream);
+
+ // Reset the starting byte for the new BLOB.
+ startIndex = 0;
+
+ // Read bytes into outByte[] and retain the number of bytes returned.
+ retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
+
+ // Continue while there are bytes beyond the size of the buffer.
+ while (retval == bufferSize)
+ {
+ writer.Write(outByte);
+ writer.Flush();
+
+ // Reposition start index to end of last buffer and fill buffer.
+ startIndex += bufferSize;
+ retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
+ }
+
+ // Write the remaining buffer.
+ writer.Write(outByte, 0, (int)retval);
+ writer.Flush();
+
+ // Close the output file.
+ writer.Close();
+ stream.Close();
+ }
+
+ // Close the reader and the connection.
+ reader.Close();
+ connection.Close();
+ //
+ }
+}
diff --git a/doc/samples/SqlCommand_ExecuteScalar_Return_Id.cs b/doc/samples/SqlCommand_ExecuteScalar_Return_Id.cs
new file mode 100644
index 0000000000..61f8029a16
--- /dev/null
+++ b/doc/samples/SqlCommand_ExecuteScalar_Return_Id.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Class1
+{
+ static void Main()
+ {
+ int ret = AddProductCategory("newval", GetConnectionString());
+ Console.WriteLine(ret.ToString());
+ Console.ReadLine();
+ }
+
+ //
+ static public int AddProductCategory(string newName, string connString)
+ {
+ Int32 newProdID = 0;
+ string sql =
+ "INSERT INTO Production.ProductCategory (Name) VALUES (@Name); "
+ + "SELECT CAST(scope_identity() AS int)";
+ using (SqlConnection conn = new SqlConnection(connString))
+ {
+ SqlCommand cmd = new SqlCommand(sql, conn);
+ cmd.Parameters.Add("@Name", SqlDbType.VarChar);
+ cmd.Parameters["@name"].Value = newName;
+ try
+ {
+ conn.Open();
+ newProdID = (Int32)cmd.ExecuteScalar();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ return (int)newProdID;
+ }
+
+ //
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=AdventureWorks;"
+ + "Integrated Security=true";
+ }
+}
diff --git a/doc/samples/SqlCommand_Intro.cs b/doc/samples/SqlCommand_Intro.cs
index b0af57ffa3..5c16f78fd5 100644
--- a/doc/samples/SqlCommand_Intro.cs
+++ b/doc/samples/SqlCommand_Intro.cs
@@ -68,7 +68,7 @@ public static SqlDataReader ExecuteReader(String connectionString, String comman
static void Main(string[] args)
{
- String connectionString = "Data Source=(local);Initial Catalog=MySchool;Integrated Security=True;Asynchronous Processing=true;";
+ String connectionString = "Data Source=(local);Initial Catalog=MySchool;Integrated Security=True;";
CountCourses(connectionString, 2012);
Console.WriteLine();
diff --git a/doc/samples/SqlConfigurableRetryLogic_OpenConnection.cs b/doc/samples/SqlConfigurableRetryLogic_OpenConnection.cs
new file mode 100644
index 0000000000..dca259fecf
--- /dev/null
+++ b/doc/samples/SqlConfigurableRetryLogic_OpenConnection.cs
@@ -0,0 +1,105 @@
+using System;
+//
+using Microsoft.Data.SqlClient;
+
+/// Detecting retriable exceptions is a vital part of the retry pattern.
+/// Before applying retry logic it is important to investigate exceptions and choose a retry provider that best fits your scenario.
+/// First, log your exceptions and find transient faults.
+/// The purpose of this sample is to illustrate how to use this feature and the condition might not be realistic.
+class RetryLogicSample
+{
+ private const string DefaultDB = "Northwind";
+ private const string CnnStringFormat = "Server=localhost; Initial Catalog={0}; Integrated Security=true; pooling=false;";
+ private const string DropDatabaseFormat = "DROP DATABASE {0}";
+
+ // For general use
+ private static SqlConnection s_generalConnection = new SqlConnection(string.Format(CnnStringFormat, DefaultDB));
+
+ static void Main(string[] args)
+ {
+ // 1. Define the retry logic parameters
+ var options = new SqlRetryLogicOption()
+ {
+ NumberOfTries = 5,
+ MaxTimeInterval = TimeSpan.FromSeconds(20),
+ DeltaTime = TimeSpan.FromSeconds(1)
+ };
+
+ // 2. Create a retry provider
+ var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);
+
+ // define the retrying event to report the execution attempts
+ provider.Retrying += (object s, SqlRetryingEventArgs e) =>
+ {
+ int attempts = e.RetryCount + 1;
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine($"attempt {attempts} - current delay time:{e.Delay} \n");
+ Console.ForegroundColor = ConsoleColor.DarkGray;
+ if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex)
+ {
+ Console.WriteLine($"{ex.Number}-{ex.Message}\n");
+ }
+ else
+ {
+ Console.WriteLine($"{e.Exceptions[e.Exceptions.Count - 1].Message}\n");
+ }
+
+ // It is not a good practice to do time-consuming tasks inside the retrying event which blocks the running task.
+ // Use parallel programming patterns to mitigate it.
+ if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
+ {
+ Console.WriteLine("This is the last chance to execute the command before throwing the exception.");
+ Console.WriteLine("Press Enter when you're ready:");
+ Console.ReadLine();
+ Console.WriteLine("continue ...");
+ }
+ };
+
+ // Open the general connection.
+ s_generalConnection.Open();
+
+ try
+ {
+ // Assume the database is being created and other services are going to connect to it.
+ RetryConnection(provider);
+ }
+ catch
+ {
+ // exception is thrown if connecting to the database isn't successful.
+ throw;
+ }
+ }
+
+ private static void ExecuteCommand(SqlConnection cn, string command)
+ {
+ using var cmd = cn.CreateCommand();
+ cmd.CommandText = command;
+ cmd.ExecuteNonQuery();
+ }
+
+ private static void RetryConnection(SqlRetryLogicBaseProvider provider)
+ {
+ // Change this if you already have a database with the same name in your database.
+ string dbName = "Invalid_DB_Open";
+
+ // Create a connection to an invalid database.
+ using var cnn = new SqlConnection(string.Format(CnnStringFormat, dbName));
+ // 3. Assign the `provider` to the connection
+ cnn.RetryLogicProvider = provider;
+ Console.WriteLine($"Connecting to the [{dbName}] ...");
+ // Manually execute the following command in SSMS to create the invalid database while the SqlConnection is attempting to connect to it.
+ // >> CREATE DATABASE Invalid_DB_Open;
+ Console.WriteLine($"Manually, run the 'CREATE DATABASE {dbName};' in the SQL Server before exceeding the {provider.RetryLogic.NumberOfTries} attempts.");
+ // the connection tries to connect to the database 5 times
+ Console.WriteLine("The first attempt, before getting into the retry logic.");
+ cnn.Open();
+ Console.WriteLine($"Connected to the [{dbName}] successfully.");
+
+ cnn.Close();
+
+ // Drop it after test
+ ExecuteCommand(s_generalConnection, string.Format(DropDatabaseFormat, dbName));
+ Console.WriteLine($"The [{dbName}] is removed.");
+ }
+}
+//
diff --git a/doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs b/doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs
new file mode 100644
index 0000000000..71ace67def
--- /dev/null
+++ b/doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs
@@ -0,0 +1,245 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Data.SqlClient;
+
+class RetryLogicSample
+{
+//
+/// Detecting retriable exceptions is a vital part of the retry pattern.
+/// Before applying retry logic it is important to investigate exceptions and choose a retry provider that best fits your scenario.
+/// First, log your exceptions and find transient faults.
+/// The purpose of this sample is to illustrate how to use this feature and the condition might not be realistic.
+
+ private const string DefaultDB = "Northwind";
+ private const string CnnStringFormat = "Server=localhost; Initial Catalog={0}; Integrated Security=true; pooling=false;";
+ private const string DropDatabaseFormat = "DROP DATABASE {0}";
+ private const string CreateDatabaseFormat = "CREATE DATABASE {0}";
+
+ // For general use
+ private static SqlConnection s_generalConnection = new SqlConnection(string.Format(CnnStringFormat, DefaultDB));
+
+ static void Main(string[] args)
+ {
+ // 1. Define the retry logic parameters
+ var options = new SqlRetryLogicOption()
+ {
+ NumberOfTries = 5,
+ MaxTimeInterval = TimeSpan.FromSeconds(20),
+ DeltaTime = TimeSpan.FromSeconds(1),
+ AuthorizedSqlCondition = null,
+ // error number 3702 : Cannot drop database "xxx" because it is currently in use.
+ TransientErrors = new int[] {3702}
+ };
+
+ // 2. Create a retry provider
+ var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);
+
+ // define the retrying event to report execution attempts
+ provider.Retrying += (object s, SqlRetryingEventArgs e) =>
+ {
+ int attempts = e.RetryCount + 1;
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine($"attempt {attempts} - current delay time:{e.Delay} \n");
+ Console.ForegroundColor = ConsoleColor.DarkGray;
+ if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex)
+ {
+ Console.WriteLine($"{ex.Number}-{ex.Message}\n");
+ }
+ else
+ {
+ Console.WriteLine($"{e.Exceptions[e.Exceptions.Count - 1].Message}\n");
+ }
+
+ // It is not good practice to do time-consuming tasks inside the retrying event which blocks the running task.
+ // Use parallel programming patterns to mitigate it.
+ if (e.RetryCount == provider.RetryLogic.NumberOfTries - 1)
+ {
+ Console.WriteLine("This is the last chance to execute the command before throwing the exception.");
+ Console.WriteLine("Press Enter when you're ready:");
+ Console.ReadLine();
+ Console.WriteLine("continue ...");
+ }
+ };
+
+ // Open a general connection.
+ s_generalConnection.Open();
+
+ try
+ {
+ // Assume the database is creating and other services are going to connect to it.
+ RetryCommand(provider);
+ }
+ catch
+ {
+ s_generalConnection.Close();
+ // exception is thrown if connecting to the database isn't successful.
+ throw;
+ }
+ s_generalConnection.Close();
+ }
+
+ private static void ExecuteCommand(SqlConnection cn, string command)
+ {
+ using var cmd = cn.CreateCommand();
+ cmd.CommandText = command;
+ cmd.ExecuteNonQuery();
+ }
+
+ private static void FindActiveSessions(SqlConnection cnn, string dbName)
+ {
+ using var cmd = cnn.CreateCommand();
+ cmd.CommandText = "DECLARE @query NVARCHAR(max) = '';" + Environment.NewLine +
+ $"SELECT @query = @query + 'KILL ' + CAST(spid as varchar(50)) + ';' FROM sys.sysprocesses WHERE dbid = DB_ID('{dbName}')" + Environment.NewLine +
+ "SELECT @query AS Active_sessions;";
+ var reader = cmd.ExecuteReader();
+ if (reader.Read())
+ {
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.Write($">> Execute the '{reader.GetString(0)}' command in SQL Server to unblock the running task.");
+ Console.ResetColor();
+ }
+ reader.Close();
+ }
+//
+//
+ private static void RetryCommand(SqlRetryLogicBaseProvider provider)
+ {
+ // Change this if you already have a database with the same name in your database.
+ string dbName = "RetryCommand_TestDatabase";
+
+ // Subscribe a new event on retry event and discover the active sessions on a database
+ EventHandler retryEvent = (object s, SqlRetryingEventArgs e) =>
+ {
+ // Run just at first execution
+ if (e.RetryCount == 1)
+ {
+ FindActiveSessions(s_generalConnection, dbName);
+ Console.WriteLine($"Before exceeding {provider.RetryLogic.NumberOfTries} attempts.");
+ }
+ };
+
+ provider.Retrying += retryEvent;
+
+ // Create a new database.
+ ExecuteCommand(s_generalConnection, string.Format(CreateDatabaseFormat, dbName));
+ Console.WriteLine($"The '{dbName}' database is created.");
+
+ // Open a connection to the newly created database to block it from being dropped.
+ using var blockingCnn = new SqlConnection(string.Format(CnnStringFormat, dbName));
+ blockingCnn.Open();
+ Console.WriteLine($"Established a connection to '{dbName}' to block it from being dropped.");
+
+ Console.WriteLine($"Dropping `{dbName}`...");
+ // Try to drop the new database.
+ RetryCommandSync(provider, dbName);
+
+ Console.WriteLine("Command executed successfully.");
+
+ provider.Retrying -= retryEvent;
+ }
+
+ private static void RetryCommandSync(SqlRetryLogicBaseProvider provider, string dbName)
+ {
+ using var cmd = s_generalConnection.CreateCommand();
+ cmd.CommandText = string.Format(DropDatabaseFormat, dbName);
+ // 3. Assign the `provider` to the command
+ cmd.RetryLogicProvider = provider;
+ Console.WriteLine("The first attempt, before getting into the retry logic.");
+ cmd.ExecuteNonQuery();
+ }
+//
+//
+ private static void RetryCommand(SqlRetryLogicBaseProvider provider)
+ {
+ // Change this if you already have a database with the same name in your database.
+ string dbName = "RetryCommand_TestDatabase";
+
+ // Subscribe to the retry event and discover active sessions in a database
+ EventHandler retryEvent = (object s, SqlRetryingEventArgs e) =>
+ {
+ // Run just at first execution
+ if (e.RetryCount == 1)
+ {
+ FindActiveSessions(s_generalConnection, dbName);
+ Console.WriteLine($"Before exceeding {provider.RetryLogic.NumberOfTries} attempts.");
+ }
+ };
+
+ provider.Retrying += retryEvent;
+
+ // Create a new database.
+ ExecuteCommand(s_generalConnection, string.Format(CreateDatabaseFormat, dbName));
+ Console.WriteLine($"The '{dbName}' database is created.");
+
+ // Open a connection to the newly created database to block it from being dropped.
+ using var blockingCnn = new SqlConnection(string.Format(CnnStringFormat, dbName));
+ blockingCnn.Open();
+ Console.WriteLine($"Established a connection to '{dbName}' to block it from being dropped.");
+
+ Console.WriteLine("Dropping the database...");
+ // Try to drop the new database.
+ RetryCommandAsync(provider, dbName).Wait();
+
+ Console.WriteLine("Command executed successfully.");
+
+ provider.Retrying -= retryEvent;
+ }
+
+ private static async Task RetryCommandAsync(SqlRetryLogicBaseProvider provider, string dbName)
+ {
+ using var cmd = s_generalConnection.CreateCommand();
+ cmd.CommandText = string.Format(DropDatabaseFormat, dbName);
+ // 3. Assign the `provider` to the command
+ cmd.RetryLogicProvider = provider;
+ Console.WriteLine("The first attempt, before getting into the retry logic.");
+ await cmd.ExecuteNonQueryAsync();
+ }
+//
+//
+ private static void RetryCommand(SqlRetryLogicBaseProvider provider)
+ {
+ // Change this if you already have a database with the same name in your database.
+ string dbName = "RetryCommand_TestDatabase";
+
+ // Subscribe to the retry event and discover the active sessions in a database
+ EventHandler retryEvent = (object s, SqlRetryingEventArgs e) =>
+ {
+ // Run just at first execution
+ if (e.RetryCount == 1)
+ {
+ FindActiveSessions(s_generalConnection, dbName);
+ Console.WriteLine($"Before exceeding {provider.RetryLogic.NumberOfTries} attempts.");
+ }
+ };
+
+ provider.Retrying += retryEvent;
+
+ // Create a new database.
+ ExecuteCommand(s_generalConnection, string.Format(CreateDatabaseFormat, dbName));
+ Console.WriteLine($"The '{dbName}' database is created.");
+
+ // Open a connection to the newly created database to block it from being dropped.
+ using var blockingCnn = new SqlConnection(string.Format(CnnStringFormat, dbName));
+ blockingCnn.Open();
+ Console.WriteLine($"Established a connection to '{dbName}' to block it from being dropped.");
+
+ Console.WriteLine("Dropping the database...");
+ // Try to drop the new database.
+ RetryCommandBeginExecuteAsync(provider, dbName).Wait();
+
+ Console.WriteLine("Command executed successfully.");
+
+ provider.Retrying -= retryEvent;
+ }
+
+ private static async Task RetryCommandBeginExecuteAsync(SqlRetryLogicBaseProvider provider, string dbName)
+ {
+ using var cmd = s_generalConnection.CreateCommand();
+ cmd.CommandText = string.Format(DropDatabaseFormat, dbName);
+ // Execute the BeginExecuteXXX and EndExecuteXXX functions by using Task.Factory.FromAsync().
+ // Apply the retry logic by using the ExecuteAsync function of the configurable retry logic provider.
+ Console.WriteLine("The first attempt, before getting into the retry logic.");
+ await provider.ExecuteAsync(cmd, () => Task.Factory.FromAsync(cmd.BeginExecuteNonQuery(), cmd.EndExecuteNonQuery));
+ }
+//
+}
diff --git a/doc/samples/SqlConfigurableRetryLogic_SqlRetryLogicOptions.cs b/doc/samples/SqlConfigurableRetryLogic_SqlRetryLogicOptions.cs
new file mode 100644
index 0000000000..fc03987a9a
--- /dev/null
+++ b/doc/samples/SqlConfigurableRetryLogic_SqlRetryLogicOptions.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Text.RegularExpressions;
+using Microsoft.Data.SqlClient;
+
+ class RetryLogicSample
+ {
+ static void Main(string[] args)
+ {
+ //
+ var RetryLogicOption = new SqlRetryLogicOption()
+ {
+ NumberOfTries = 5,
+ // Declare the error number 102 as a transient error to apply the retry logic when it occurs.
+ TransientErrors = new int[] { 102 },
+ // When a SqlCommand executes out of a transaction,
+ // the retry logic will apply if it contains a 'select' keyword.
+ AuthorizedSqlCondition = x => string.IsNullOrEmpty(x)
+ || Regex.IsMatch(x, @"\b(SELECT)\b", RegexOptions.IgnoreCase),
+ DeltaTime = TimeSpan.FromSeconds(1),
+ MaxTimeInterval = TimeSpan.FromSeconds(60),
+ MinTimeInterval = TimeSpan.FromSeconds(3)
+ };
+ //
+ }
+ }
diff --git a/doc/samples/SqlConfigurableRetryLogic_StepByStep_CustomProvider.cs b/doc/samples/SqlConfigurableRetryLogic_StepByStep_CustomProvider.cs
new file mode 100644
index 0000000000..a30e05389d
--- /dev/null
+++ b/doc/samples/SqlConfigurableRetryLogic_StepByStep_CustomProvider.cs
@@ -0,0 +1,255 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Data.SqlClient;
+
+namespace CustomCRL_Doc
+{
+ class Program
+ {
+ private const string CnnStringFormat = "Server=localhost; Initial Catalog=Northwind; Integrated Security=true; pooling=false; Timeout=1";
+
+ static void Main(string[] args)
+ {
+ RetryConnection(CnnStringFormat);
+ }
+
+ private static void RetryConnection(string connectionString)
+ {
+ //
+ // Define the retry logic parameters
+ var options = new SqlRetryLogicOption()
+ {
+ // Tries 5 times before throwing an exception
+ NumberOfTries = 5,
+ // Preferred gap time to delay before retry
+ DeltaTime = TimeSpan.FromSeconds(1),
+ // Maximum gap time for each delay time before retry
+ MaxTimeInterval = TimeSpan.FromSeconds(20),
+ // SqlException retriable error numbers
+ TransientErrors = new int[] { 4060, 1024, 1025}
+ };
+ //
+
+ //
+ // Create a custom retry logic provider
+ SqlRetryLogicBaseProvider provider = CustomRetry.CreateCustomProvider(options);
+ //
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object
+ // Set the retry logic provider on the connection instance
+ connection.RetryLogicProvider = provider;
+ // Establishing the connection will trigger retry if one of the given transient failure occurs.
+ connection.Open();
+ //
+ }
+ }
+ }
+
+ public class CustomRetry
+ {
+ //
+ public static SqlRetryLogicBaseProvider CreateCustomProvider(SqlRetryLogicOption options)
+ {
+ // 1. create an enumerator instance
+ CustomEnumerator customEnumerator = new CustomEnumerator(options.DeltaTime, options.MaxTimeInterval, options.MinTimeInterval);
+ // 2. Use the enumerator object to create a new RetryLogic instance
+ CustomRetryLogic customRetryLogic = new CustomRetryLogic(5, customEnumerator, (e) => TransientErrorsCondition(e, options.TransientErrors));
+ // 3. Create a provider using the RetryLogic object
+ CustomProvider customProvider = new CustomProvider(customRetryLogic);
+ return customProvider;
+ }
+ //
+
+ //
+ // Return true if the exception is a transient fault.
+ private static bool TransientErrorsCondition(Exception e, IEnumerable retriableConditions)
+ {
+ bool result = false;
+
+ // Assess only SqlExceptions
+ if (retriableConditions != null && e is SqlException ex)
+ {
+ foreach (SqlError item in ex.Errors)
+ {
+ // Check each error number to see if it is a retriable error number
+ if (retriableConditions.Contains(item.Number))
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ // Other types of exceptions can also be assessed
+ else if (e is TimeoutException)
+ {
+ result = true;
+ }
+ return result;
+ }
+ //
+ }
+
+ //
+ public class CustomEnumerator : SqlRetryIntervalBaseEnumerator
+ {
+ // Set the maximum acceptable time to 4 minutes
+ private readonly TimeSpan _maxValue = TimeSpan.FromMinutes(4);
+
+ public CustomEnumerator(TimeSpan timeInterval, TimeSpan maxTime, TimeSpan minTime)
+ : base(timeInterval, maxTime, minTime) {}
+
+ // Return fixed time on each request
+ protected override TimeSpan GetNextInterval()
+ {
+ return GapTimeInterval;
+ }
+
+ // Override the validate method with the new time range validation
+ protected override void Validate(TimeSpan timeInterval, TimeSpan maxTimeInterval, TimeSpan minTimeInterval)
+ {
+ if (minTimeInterval < TimeSpan.Zero || minTimeInterval > _maxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(minTimeInterval));
+ }
+
+ if (maxTimeInterval < TimeSpan.Zero || maxTimeInterval > _maxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(maxTimeInterval));
+ }
+
+ if (timeInterval < TimeSpan.Zero || timeInterval > _maxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(timeInterval));
+ }
+
+ if (maxTimeInterval < minTimeInterval)
+ {
+ throw new ArgumentOutOfRangeException(nameof(minTimeInterval));
+ }
+ }
+ }
+ //
+
+ //
+ public class CustomRetryLogic : SqlRetryLogicBase
+ {
+ // Maximum number of attempts
+ private const int maxAttempts = 20;
+
+ public CustomRetryLogic(int numberOfTries,
+ SqlRetryIntervalBaseEnumerator enumerator,
+ Predicate transientPredicate)
+ {
+ if (!(numberOfTries > 0 && numberOfTries <= maxAttempts))
+ {
+ // 'numberOfTries' should be between 1 and 20.
+ throw new ArgumentOutOfRangeException(nameof(numberOfTries));
+ }
+
+ // Assign parameters to the relevant properties
+ NumberOfTries = numberOfTries;
+ RetryIntervalEnumerator = enumerator;
+ TransientPredicate = transientPredicate;
+ Current = 0;
+ }
+
+ // Prepare this object for the next round
+ public override void Reset()
+ {
+ Current = 0;
+ RetryIntervalEnumerator.Reset();
+ }
+
+ public override bool TryNextInterval(out TimeSpan intervalTime)
+ {
+ intervalTime = TimeSpan.Zero;
+ // First try has occurred before starting the retry process.
+ // Check if retry is still allowed
+ bool result = Current < NumberOfTries - 1;
+
+ if (result)
+ {
+ // Increase the number of attempts
+ Current++;
+ // It's okay if the RetryIntervalEnumerator gets to the last value before we've reached our maximum number of attempts.
+ // MoveNext() will simply leave the enumerator on the final interval value and we will repeat that for the final attempts.
+ RetryIntervalEnumerator.MoveNext();
+ // Receive the current time from enumerator
+ intervalTime = RetryIntervalEnumerator.Current;
+ }
+ return result;
+ }
+ }
+ //
+
+ //
+ public class CustomProvider : SqlRetryLogicBaseProvider
+ {
+ // Preserve the given retryLogic on creation
+ public CustomProvider(SqlRetryLogicBase retryLogic)
+ {
+ RetryLogic = retryLogic;
+ }
+
+ public override TResult Execute(object sender, Func function)
+ {
+ // Create a list to save transient exceptions to report later if necessary
+ IList exceptions = new List();
+ // Prepare it before reusing
+ RetryLogic.Reset();
+ // Create an infinite loop to attempt the defined maximum number of tries
+ do
+ {
+ try
+ {
+ // Try to invoke the function
+ return function.Invoke();
+ }
+ // Catch any type of exception for further investigation
+ catch (Exception e)
+ {
+ // Ask the RetryLogic object if this exception is a transient error
+ if (RetryLogic.TransientPredicate(e))
+ {
+ // Add the exception to the list of exceptions we've retried on
+ exceptions.Add(e);
+ // Ask the RetryLogic for the next delay time before the next attempt to run the function
+ if (RetryLogic.TryNextInterval(out TimeSpan gapTime))
+ {
+ Console.WriteLine($"Wait for {gapTime} before next try");
+ // Wait before next attempt
+ Thread.Sleep(gapTime);
+ }
+ else
+ {
+ // Number of attempts has exceeded the maximum number of tries
+ throw new AggregateException("The number of retries has exceeded the maximum number of attempts.", exceptions);
+ }
+ }
+ else
+ {
+ // If the exception wasn't a transient failure throw the original exception
+ throw;
+ }
+ }
+ } while (true);
+ }
+
+ public override Task ExecuteAsync(object sender, Func> function, CancellationToken cancellationToken = default)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override Task ExecuteAsync(object sender, Func function, CancellationToken cancellationToken = default)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ //
+}
diff --git a/doc/samples/SqlConfigurableRetryLogic_StepByStep_OpenConnection.cs b/doc/samples/SqlConfigurableRetryLogic_StepByStep_OpenConnection.cs
new file mode 100644
index 0000000000..4ae3bc4c5f
--- /dev/null
+++ b/doc/samples/SqlConfigurableRetryLogic_StepByStep_OpenConnection.cs
@@ -0,0 +1,44 @@
+using System;
+using Microsoft.Data.SqlClient;
+
+// The purpose of this sample is to illustrate how to use this feature and the example conditions might not be realistic.
+class RetryLogicSample
+{
+ private const string CnnStringFormat = "Server=localhost; Initial Catalog=Northwind; Integrated Security=true; pooling=false;";
+
+ static void Main(string[] args)
+ {
+ RetryConnection(CnnStringFormat);
+ }
+ private static void RetryConnection(string connectionString)
+ {
+ //
+ // Define the retry logic parameters
+ var options = new SqlRetryLogicOption()
+ {
+ // Tries 5 times before throwing an exception
+ NumberOfTries = 5,
+ // Preferred gap time to delay before retry
+ DeltaTime = TimeSpan.FromSeconds(1),
+ // Maximum gap time for each delay time before retry
+ MaxTimeInterval = TimeSpan.FromSeconds(20)
+ };
+ //
+
+ //
+ // Create a retry logic provider
+ SqlRetryLogicBaseProvider provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options);
+ //
+
+ using(SqlConnection connection = new SqlConnection(connectionString))
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object
+ // Set the retry logic provider on the connection instance
+ connection.RetryLogicProvider = provider;
+ // Establishing the connection will retry if a transient failure occurs.
+ connection.Open();
+ //
+ }
+ }
+}
diff --git a/doc/samples/SqlConnectionStringBuilder.cs b/doc/samples/SqlConnectionStringBuilder.cs
index bb19d43b16..f1c3252880 100644
--- a/doc/samples/SqlConnectionStringBuilder.cs
+++ b/doc/samples/SqlConnectionStringBuilder.cs
@@ -27,7 +27,6 @@ static void Main()
// you can work with individual items.
Console.WriteLine(builder.Password);
builder.Password = "new@1Password";
- builder.AsynchronousProcessing = true;
// You can refer to connection keys using strings,
// as well. When you use this technique (the default
diff --git a/doc/samples/SqlConnectionStringBuilder_AsynchronousProcessing.cs b/doc/samples/SqlConnectionStringBuilder_AsynchronousProcessing.cs
deleted file mode 100644
index b3706e86bd..0000000000
--- a/doc/samples/SqlConnectionStringBuilder_AsynchronousProcessing.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using System.Data;
-//
-using Microsoft.Data.SqlClient;
-using System.Threading;
-
-class Program
-{
- static void Main()
- {
- // Create a SqlConnectionStringBuilder instance,
- // and ensure that it is set up for asynchronous processing.
- SqlConnectionStringBuilder builder =
- new SqlConnectionStringBuilder(GetConnectionString());
- // Asynchronous method calls won't work unless you
- // have added this option, or have added
- // the clause "Asynchronous Processing=true"
- // to the connection string.
- builder.AsynchronousProcessing = true;
-
- string commandText =
- "UPDATE Production.Product SET ReorderPoint = ReorderPoint + 1 " +
- "WHERE ReorderPoint IS NOT Null;" +
- "WAITFOR DELAY '0:0:3';" +
- "UPDATE Production.Product SET ReorderPoint = ReorderPoint - 1 " +
- "WHERE ReorderPoint IS NOT Null";
- RunCommandAsynchronously(commandText, builder.ConnectionString);
-
- Console.WriteLine("Press any key to finish.");
- Console.ReadLine();
- }
-
- private static string GetConnectionString()
- {
- // To avoid storing the connection string in your code,
- // you can retrieve it from a configuration file.
- return "Data Source=(local);Integrated Security=SSPI;" +
- "Initial Catalog=AdventureWorks";
- }
-
- private static void RunCommandAsynchronously(string commandText,
- string connectionString)
- {
- // Given command text and connection string, asynchronously execute
- // the specified command against the connection. For this example,
- // the code displays an indicator as it's working, verifying the
- // asynchronous behavior.
- using (SqlConnection connection = new SqlConnection(connectionString))
- {
- try
- {
- int count = 0;
- SqlCommand command = new SqlCommand(commandText, connection);
- connection.Open();
- IAsyncResult result = command.BeginExecuteNonQuery();
- while (!result.IsCompleted)
- {
- Console.WriteLine("Waiting {0}.", count);
- // Wait for 1/10 second, so the counter
- // doesn't consume all available resources
- // on the main thread.
- Thread.Sleep(100);
- count += 1;
- }
- Console.WriteLine("Command complete. Affected {0} rows.",
- command.EndExecuteNonQuery(result));
-
- }
- catch (SqlException ex)
- {
- Console.WriteLine(
- "Error {0}: Microsoft.Data.SqlClient.SqlConnectionStringBuilder",
- ex.Number, ex.Message);
- }
- catch (InvalidOperationException ex)
- {
- Console.WriteLine("Error: {0}", ex.Message);
- }
- catch (Exception ex)
- {
- // You might want to pass these errors
- // back out to the caller.
- Console.WriteLine("Error: {0}", ex.Message);
- }
- }
- }
-}
-//
diff --git a/doc/samples/SqlConnectionStringBuilder_Values.cs b/doc/samples/SqlConnectionStringBuilder_Values.cs
index ae6f3b0f32..553a02e5fb 100644
--- a/doc/samples/SqlConnectionStringBuilder_Values.cs
+++ b/doc/samples/SqlConnectionStringBuilder_Values.cs
@@ -23,7 +23,7 @@ private static string GetConnectionString()
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Integrated Security=SSPI;" +
- "Initial Catalog=AdventureWorks; Asynchronous Processing=true";
+ "Initial Catalog=AdventureWorks";
}
}
//
diff --git a/doc/samples/SqlConnection_BeginTransaction.cs b/doc/samples/SqlConnection_BeginTransaction.cs
index 9665c33c12..13f9c0414d 100644
--- a/doc/samples/SqlConnection_BeginTransaction.cs
+++ b/doc/samples/SqlConnection_BeginTransaction.cs
@@ -24,7 +24,7 @@ private static void ExecuteSqlTransaction(string connectionString)
SqlTransaction transaction;
// Start a local transaction.
- transaction = connection.BeginTransaction("SampleTransaction");
+ transaction = connection.BeginTransaction();
// Must assign both transaction object and connection
// to Command object for a pending local transaction
diff --git a/doc/samples/SqlConnection_BeginTransaction2.cs b/doc/samples/SqlConnection_BeginTransaction2.cs
index 9665c33c12..1be9f5987d 100644
--- a/doc/samples/SqlConnection_BeginTransaction2.cs
+++ b/doc/samples/SqlConnection_BeginTransaction2.cs
@@ -52,7 +52,7 @@ private static void ExecuteSqlTransaction(string connectionString)
// Attempt to roll back the transaction.
try
{
- transaction.Rollback();
+ transaction.Rollback("SampleTransaction");
}
catch (Exception ex2)
{
diff --git a/doc/samples/SqlConnection_BeginTransaction3.cs b/doc/samples/SqlConnection_BeginTransaction3.cs
index 44eb020ff7..c68284f6d9 100644
--- a/doc/samples/SqlConnection_BeginTransaction3.cs
+++ b/doc/samples/SqlConnection_BeginTransaction3.cs
@@ -47,7 +47,7 @@ private static void ExecuteSqlTransaction(string connectionString)
{
try
{
- transaction.Rollback();
+ transaction.Rollback("SampleTransaction");
}
catch (SqlException ex)
{
diff --git a/doc/samples/SqlConnection_GetSchema.cs b/doc/samples/SqlConnection_GetSchema.cs
index 64b07aaef5..8ca75b225e 100644
--- a/doc/samples/SqlConnection_GetSchema.cs
+++ b/doc/samples/SqlConnection_GetSchema.cs
@@ -7,7 +7,7 @@ class Program
{
static void Main(string[] args)
{
- using (SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=MySchool;Integrated Security=True;Asynchronous Processing=true;"))
+ using (SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=MySchool;Integrated Security=True;"))
{
conn.Open();
diff --git a/doc/samples/SqlConnection_GetSchema_Restriction.cs b/doc/samples/SqlConnection_GetSchema_Restriction.cs
new file mode 100644
index 0000000000..209b0b8c3a
--- /dev/null
+++ b/doc/samples/SqlConnection_GetSchema_Restriction.cs
@@ -0,0 +1,40 @@
+//
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = AdventureWorks";
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ connection.Open();
+
+ // Specify the restrictions.
+ string[] restrictions = new string[4];
+ restrictions[1] = "Sales";
+ System.Data.DataTable table = connection.GetSchema("Tables", restrictions);
+
+ // Display the contents of the table.
+ DisplayData(table);
+ Console.WriteLine("Press any key to continue.");
+ Console.ReadKey();
+ }
+ }
+
+ private static void DisplayData(System.Data.DataTable table)
+ {
+ foreach (System.Data.DataRow row in table.Rows)
+ {
+ foreach (System.Data.DataColumn col in table.Columns)
+ {
+ Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
+ }
+ Console.WriteLine("============================");
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlConnection_GetSchema_Tables.cs b/doc/samples/SqlConnection_GetSchema_Tables.cs
new file mode 100644
index 0000000000..34f04439a6
--- /dev/null
+++ b/doc/samples/SqlConnection_GetSchema_Tables.cs
@@ -0,0 +1,36 @@
+//
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = AdventureWorks";
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ connection.Open();
+ DataTable table = connection.GetSchema("Tables");
+
+ // Display the contents of the table.
+ DisplayData(table);
+ Console.WriteLine("Press any key to continue.");
+ Console.ReadKey();
+ }
+ }
+
+ private static void DisplayData(System.Data.DataTable table)
+ {
+ foreach (System.Data.DataRow row in table.Rows)
+ {
+ foreach (System.Data.DataColumn col in table.Columns)
+ {
+ Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
+ }
+ Console.WriteLine("============================");
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlConnection_OpenAsync_ContinueWith.cs b/doc/samples/SqlConnection_OpenAsync_ContinueWith.cs
new file mode 100644
index 0000000000..1bc63d3af0
--- /dev/null
+++ b/doc/samples/SqlConnection_OpenAsync_ContinueWith.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Data;
+//
+using Microsoft.Data.SqlClient;
+using System.Threading.Tasks;
+
+class A
+{
+ static void ProductList(IAsyncResult result) { }
+
+ public static void Main()
+ {
+ // AsyncCallback productList = new AsyncCallback(ProductList);
+ // SqlConnection conn = new SqlConnection("Data Source=(local); Initial Catalog=NorthWind; Integrated Security=SSPI");
+ // conn.Open();
+ // SqlCommand cmd = new SqlCommand("select top 2 * from orders", conn);
+ // IAsyncResult ia = cmd.BeginExecuteReader(productList, cmd);
+
+ AsyncCallback productList = new AsyncCallback(ProductList);
+ SqlConnection conn = new SqlConnection("Data Source=(local); Initial Catalog=NorthWind; Integrated Security=SSPI");
+ conn.OpenAsync().ContinueWith((task) => {
+ SqlCommand cmd = new SqlCommand("select top 2 * from orders", conn);
+ IAsyncResult ia = cmd.BeginExecuteReader(productList, cmd);
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
+ }
+}
+//
+
+class B
+{
+ static void ProductList(IAsyncResult result) { }
+
+ public static void Main()
+ {
+ //
+ AsyncCallback productList = new AsyncCallback(ProductList);
+ SqlConnection conn = new SqlConnection("Data Source=(local); Initial Catalog=NorthWind; Integrated Security=SSPI");
+ conn.Open();
+ SqlCommand cmd = new SqlCommand("select top 2 * from orders", conn);
+ IAsyncResult ia = cmd.BeginExecuteReader(productList, cmd);
+ //
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_Batch.cs b/doc/samples/SqlDataAdapter_Batch.cs
new file mode 100644
index 0000000000..f7deb7e87d
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_Batch.cs
@@ -0,0 +1,69 @@
+using System;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace DataAdapterTest
+{
+ class Program
+ {
+ static void Main()
+ {
+ }
+
+ //
+ public static void BatchUpdate(DataTable dataTable, Int32 batchSize)
+ {
+ // Assumes GetConnectionString() returns a valid connection string.
+ string connectionString = GetConnectionString();
+
+ // Connect to the AdventureWorks database.
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ // Create a SqlDataAdapter.
+ SqlDataAdapter adapter = new SqlDataAdapter();
+
+ // Set the UPDATE command and parameters.
+ adapter.UpdateCommand = new SqlCommand(
+ "UPDATE Production.ProductCategory SET "
+ + "Name=@Name WHERE ProductCategoryID=@ProdCatID;",
+ connection);
+ adapter.UpdateCommand.Parameters.Add("@Name",
+ SqlDbType.NVarChar, 50, "Name");
+ adapter.UpdateCommand.Parameters.Add("@ProdCatID",
+ SqlDbType.Int, 4, "ProductCategoryID");
+ adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
+
+ // Set the INSERT command and parameter.
+ adapter.InsertCommand = new SqlCommand(
+ "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);",
+ connection);
+ adapter.InsertCommand.Parameters.Add("@Name",
+ SqlDbType.NVarChar, 50, "Name");
+ adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
+
+ // Set the DELETE command and parameter.
+ adapter.DeleteCommand = new SqlCommand(
+ "DELETE FROM Production.ProductCategory "
+ + "WHERE ProductCategoryID=@ProdCatID;", connection);
+ adapter.DeleteCommand.Parameters.Add("@ProdCatID",
+ SqlDbType.Int, 4, "ProductCategoryID");
+ adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;
+
+ // Set the batch size.
+ adapter.UpdateBatchSize = batchSize;
+
+ // Execute the update.
+ adapter.Update(dataTable);
+ }
+ }
+ //
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=AdventureWorks;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_Concurrency.cs b/doc/samples/SqlDataAdapter_Concurrency.cs
new file mode 100644
index 0000000000..fd40eb9f7f
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_Concurrency.cs
@@ -0,0 +1,62 @@
+//
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = Northwind";
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ // Assumes connection is a valid SqlConnection.
+ SqlDataAdapter adapter = new SqlDataAdapter(
+ "SELECT CustomerID, CompanyName FROM Customers ORDER BY CustomerID",
+ connection);
+
+ // The Update command checks for optimistic concurrency violations
+ // in the WHERE clause.
+ adapter.UpdateCommand = new SqlCommand("UPDATE Customers Set CustomerID = @CustomerID, CompanyName = @CompanyName " +
+ "WHERE CustomerID = @oldCustomerID AND CompanyName = @oldCompanyName", connection);
+ adapter.UpdateCommand.Parameters.Add(
+ "@CustomerID", SqlDbType.NChar, 5, "CustomerID");
+ adapter.UpdateCommand.Parameters.Add(
+ "@CompanyName", SqlDbType.NVarChar, 30, "CompanyName");
+
+ // Pass the original values to the WHERE clause parameters.
+ SqlParameter parameter = adapter.UpdateCommand.Parameters.Add(
+ "@oldCustomerID", SqlDbType.NChar, 5, "CustomerID");
+ parameter.SourceVersion = DataRowVersion.Original;
+ parameter = adapter.UpdateCommand.Parameters.Add(
+ "@oldCompanyName", SqlDbType.NVarChar, 30, "CompanyName");
+ parameter.SourceVersion = DataRowVersion.Original;
+
+ // Add the RowUpdated event handler.
+ adapter.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
+
+ DataSet dataSet = new DataSet();
+ adapter.Fill(dataSet, "Customers");
+
+ // Modify the DataSet contents.
+ adapter.Update(dataSet, "Customers");
+
+ foreach (DataRow dataRow in dataSet.Tables["Customers"].Rows)
+ {
+ if (dataRow.HasErrors)
+ Console.WriteLine(dataRow[0] + "\n" + dataRow.RowError);
+ }
+ }
+ }
+
+ protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
+ {
+ if (args.RecordsAffected == 0)
+ {
+ args.Row.RowError = "Optimistic Concurrency Violation Encountered";
+ args.Status = UpdateStatus.SkipCurrentRow;
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlDataAdapter_Events.cs b/doc/samples/SqlDataAdapter_Events.cs
new file mode 100644
index 0000000000..deacdeb298
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_Events.cs
@@ -0,0 +1,95 @@
+using System;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace DataAdapterTest
+{
+ class Program
+ {
+ static void Main()
+ {
+ }
+
+ //
+ static DataSet DataAdapterEventsDemo(SqlConnection connection, DataSet custDS)
+ {
+ // Assumes that connection is a valid SqlConnection object
+ // and custDS includes the Customers table.
+ SqlDataAdapter custAdapter = new SqlDataAdapter(
+ "SELECT CustomerID, CompanyName FROM Customers", connection);
+
+ // Add handlers.
+ custAdapter.RowUpdating += new SqlRowUpdatingEventHandler(OnRowUpdating);
+ custAdapter.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
+
+ // Set DataAdapter command properties, fill DataSet, modify DataSet.
+ custAdapter.Update(custDS, "Customers");
+
+ // Remove handlers.
+ custAdapter.RowUpdating -= new SqlRowUpdatingEventHandler(OnRowUpdating);
+ custAdapter.RowUpdated -= new SqlRowUpdatedEventHandler(OnRowUpdated);
+
+ return custDS;
+ }
+
+ protected static void OnRowUpdating(object sender, SqlRowUpdatingEventArgs args)
+ {
+ if (args.StatementType == StatementType.Delete)
+ {
+ // Saves the removing rows with additional information in a file.
+ System.IO.TextWriter tw = System.IO.File.AppendText("Deletes.log");
+ tw.WriteLine(
+ "{0}: Customer {1} Deleted.", DateTime.Now,
+ args.Row["CustomerID", DataRowVersion.Original]);
+ tw.Close();
+ }
+ }
+
+ protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
+ {
+ if (args.Status == UpdateStatus.ErrorsOccurred)
+ {
+ // Adds the error message to the row and skips from it.
+ args.Row.RowError = args.Errors.Message;
+ args.Status = UpdateStatus.SkipCurrentRow;
+ }
+ }
+ //
+
+ //
+ static DataSet DataAdapterFillAndError(SqlDataAdapter adapter)
+ {
+ // Assuemes adapter is a valid SqlDataAdapter object.
+ adapter.FillError += new FillErrorEventHandler(FillError);
+
+ DataSet dataSet = new DataSet();
+ adapter.Fill(dataSet);
+ return dataSet;
+ }
+
+ protected static void FillError(object sender, FillErrorEventArgs args)
+ {
+ if (args.Errors.GetType() == typeof(System.OverflowException))
+ {
+ // Code to handle precision loss.
+ // Add a row to table using the values from the first two columns.
+ DataRow myRow = args.DataTable.Rows.Add(new object[]
+ {args.Values[0], args.Values[1], DBNull.Value});
+ //Set the RowError containing the value for the third column.
+ myRow.RowError =
+ "OverflowException Encountered. Value from data source: " +
+ args.Values[2];
+ args.Continue = true;
+ }
+ }
+ //
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_FillDataSet.cs b/doc/samples/SqlDataAdapter_FillDataSet.cs
new file mode 100644
index 0000000000..0365bedc40
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_FillDataSet.cs
@@ -0,0 +1,114 @@
+using System;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace DataAdapterTest
+{
+ class Program
+ {
+ static void Main()
+ {
+ string s = GetConnectionString();
+ SqlConnection c = new SqlConnection(s);
+ GetCustomers(c);
+ PrintCustomersOrders(c, c);
+ CustomerFillSchema1(c);
+ CustomerFillSchema2(c);
+ Console.ReadLine();
+ }
+
+ static DataSet GetCustomers(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object.
+ string queryString =
+ "SELECT CustomerID, CompanyName FROM dbo.Customers";
+ SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
+
+ DataSet customers = new DataSet();
+ adapter.Fill(customers, "Customers");
+ //
+ return customers;
+ }
+ }
+
+ static void PrintCustomersOrders(SqlConnection customerConnection, SqlConnection orderConnection)
+ {
+ using (customerConnection)
+ using (orderConnection)
+ {
+ //
+ // Assumes that customerConnection and orderConnection are valid SqlConnection objects.
+ SqlDataAdapter custAdapter = new SqlDataAdapter(
+ "SELECT * FROM dbo.Customers", customerConnection);
+ SqlDataAdapter ordAdapter = new SqlDataAdapter(
+ "SELECT * FROM Orders", orderConnection);
+
+ DataSet customerOrders = new DataSet();
+
+ custAdapter.Fill(customerOrders, "Customers");
+ ordAdapter.Fill(customerOrders, "Orders");
+
+ DataRelation relation = customerOrders.Relations.Add("CustOrders",
+ customerOrders.Tables["Customers"].Columns["CustomerID"],
+ customerOrders.Tables["Orders"].Columns["CustomerID"]);
+
+ foreach (DataRow pRow in customerOrders.Tables["Customers"].Rows)
+ {
+ Console.WriteLine(pRow["CustomerID"]);
+ foreach (DataRow cRow in pRow.GetChildRows(relation))
+ Console.WriteLine("\t" + cRow["OrderID"]);
+ }
+ //
+ }
+ }
+
+ static DataSet CustomerFillSchema1(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object.
+ DataSet custDataSet = new DataSet();
+
+ SqlDataAdapter custAdapter = new SqlDataAdapter(
+ "SELECT * FROM dbo.Customers", connection);
+
+ custAdapter.FillSchema(custDataSet, SchemaType.Source, "Customers");
+ custAdapter.Fill(custDataSet, "Customers");
+ //
+
+ return custDataSet;
+ }
+ }
+
+ static DataSet CustomerFillSchema2(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object.
+ DataSet custDataSet = new DataSet();
+
+ SqlDataAdapter custAdapter = new SqlDataAdapter(
+ "SELECT * FROM dbo.Customers", connection);
+
+ custAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
+ custAdapter.Fill(custDataSet, "Customers");
+ //
+
+ return custDataSet;
+ }
+ }
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_MergeIdentity.cs b/doc/samples/SqlDataAdapter_MergeIdentity.cs
new file mode 100644
index 0000000000..010beda2c7
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_MergeIdentity.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main()
+ {
+ string connectionString = GetConnectionString();
+ MergeIdentityColumns(connectionString);
+ Console.ReadLine();
+ }
+
+ //
+ private static void MergeIdentityColumns(string connectionString)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ // Create the DataAdapter
+ SqlDataAdapter adapter = new SqlDataAdapter(
+ "SELECT ShipperID, CompanyName FROM dbo.Shippers",
+ connection);
+
+ //Add the InsertCommand to retrieve new identity value.
+ adapter.InsertCommand = new SqlCommand(
+ "INSERT INTO dbo.Shippers (CompanyName) " +
+ "VALUES (@CompanyName); " +
+ "SELECT ShipperID, CompanyName FROM dbo.Shippers " +
+ "WHERE ShipperID = SCOPE_IDENTITY();", connection);
+
+ // Add the parameter for the inserted value.
+ adapter.InsertCommand.Parameters.Add(
+ new SqlParameter("@CompanyName", SqlDbType.NVarChar, 40,
+ "CompanyName"));
+ adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.Both;
+
+ // MissingSchemaAction adds any missing schema to
+ // the DataTable, including identity columns
+ adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
+
+ // Fill the DataTable.
+ DataTable shipper = new DataTable();
+ adapter.Fill(shipper);
+
+ // Add a new shipper.
+ DataRow newRow = shipper.NewRow();
+ newRow["CompanyName"] = "New Shipper";
+ shipper.Rows.Add(newRow);
+
+ // Add changed rows to a new DataTable. This
+ // DataTable will be used by the DataAdapter.
+ DataTable dataChanges = shipper.GetChanges();
+
+ // Add the event handler.
+ adapter.RowUpdated +=
+ new SqlRowUpdatedEventHandler(OnRowUpdated);
+
+ adapter.Update(dataChanges);
+ connection.Close();
+
+ // Merge the updates.
+ shipper.Merge(dataChanges);
+
+ // Commit the changes.
+ shipper.AcceptChanges();
+
+ Console.WriteLine("Rows after merge.");
+ foreach (DataRow row in shipper.Rows)
+ {
+ {
+ Console.WriteLine("{0}: {1}", row[0], row[1]);
+ }
+ }
+ }
+ }
+ //
+
+ //
+ protected static void OnRowUpdated(
+ object sender, SqlRowUpdatedEventArgs e)
+ {
+ // If this is an insert, then skip this row.
+ if (e.StatementType == StatementType.Insert)
+ {
+ e.Status = UpdateStatus.SkipCurrentRow;
+ }
+ }
+ //
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=true";
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_Paging.cs b/doc/samples/SqlDataAdapter_Paging.cs
new file mode 100644
index 0000000000..511c05ba16
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_Paging.cs
@@ -0,0 +1,91 @@
+using System;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace DataAdapterTest
+{
+ class Program
+ {
+ static void Main()
+ {
+ string s = GetConnectionString();
+ SqlConnection c = new SqlConnection(s);
+ GetOrders_Fill(c);
+ GetOrders_Select(c);
+ Console.ReadLine();
+ }
+
+ static DataSet GetOrders_Fill(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ int currentIndex = 0;
+ int pageSize = 5;
+
+ string orderSQL = "SELECT * FROM Orders ORDER BY OrderID";
+ // Assumes that connection is a valid SqlConnection object.
+ SqlDataAdapter adapter = new SqlDataAdapter(orderSQL, connection);
+
+ DataSet dataSet = new DataSet();
+ adapter.Fill(dataSet, currentIndex, pageSize, "Orders");
+ //
+
+ // Retrieve the next page.
+ //
+ currentIndex += pageSize;
+
+ // Assumes that dataset and adapter are valid objects.
+ dataSet.Tables["Orders"].Rows.Clear();
+ adapter.Fill(dataSet, currentIndex, pageSize, "Orders");
+ //
+
+ return dataSet;
+ }
+ }
+
+ static DataSet GetOrders_Select(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ int pageSize = 5;
+
+ string orderSQL = "SELECT TOP " + pageSize +
+ " * FROM Orders ORDER BY OrderID";
+
+ // Assumes that connection is a valid SqlConnection object.
+ SqlDataAdapter adapter = new SqlDataAdapter(orderSQL, connection);
+
+ DataSet dataSet = new DataSet();
+ adapter.Fill(dataSet, "Orders");
+ //
+
+ //
+ string lastRecord =
+ dataSet.Tables["Orders"].Rows[pageSize - 1]["OrderID"].ToString();
+ //
+
+ //
+ orderSQL = "SELECT TOP " + pageSize +
+ " * FROM Orders WHERE OrderID > " + lastRecord + " ORDER BY OrderID";
+ adapter.SelectCommand.CommandText = orderSQL;
+
+ dataSet.Tables["Orders"].Rows.Clear();
+
+ adapter.Fill(dataSet, "Orders");
+ //
+
+ return dataSet;
+ }
+ }
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_Properties.cs b/doc/samples/SqlDataAdapter_Properties.cs
new file mode 100644
index 0000000000..d66385c5d8
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_Properties.cs
@@ -0,0 +1,206 @@
+//
+using System;
+using System.Data;
+using System.Data.Common;
+using Microsoft.Data.SqlClient;
+using System.Linq;
+using CSDataAdapterOperations.Properties;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ Settings settings = new Settings();
+
+ // Copy the data from the database. Get the table Department and Course from the database.
+ String selectString = @"SELECT [DepartmentID],[Name],[Budget],[StartDate],[Administrator]
+ FROM [MySchool].[dbo].[Department];
+
+ SELECT [CourseID],@Year as [Year],Max([Title]) as [Title],
+ Max([Credits]) as [Credits],Max([DepartmentID]) as [DepartmentID]
+ FROM [MySchool].[dbo].[Course]
+ Group by [CourseID]";
+
+ DataSet mySchool = new DataSet();
+
+ SqlCommand selectCommand = new SqlCommand(selectString);
+ SqlParameter parameter = selectCommand.Parameters.Add("@Year", SqlDbType.SmallInt, 2);
+ parameter.Value = new Random(DateTime.Now.Millisecond).Next(9999);
+
+ // Use DataTableMapping to map the source tables and the destination tables.
+ DataTableMapping[] tableMappings = { new DataTableMapping("Table", "Department"), new DataTableMapping("Table1", "Course") };
+ CopyData(mySchool, settings.MySchoolConnectionString, selectCommand, tableMappings);
+
+ Console.WriteLine("The following tables are from the database.");
+ foreach (DataTable table in mySchool.Tables)
+ {
+ Console.WriteLine(table.TableName);
+ ShowDataTable(table);
+ }
+
+ // Roll back the changes
+ DataTable department = mySchool.Tables["Department"];
+ DataTable course = mySchool.Tables["Course"];
+
+ department.Rows[0]["Name"] = "New" + department.Rows[0][1];
+ course.Rows[0]["Title"] = "New" + course.Rows[0]["Title"];
+ course.Rows[0]["Credits"] = 10;
+
+ Console.WriteLine("After we changed the tables:");
+ foreach (DataTable table in mySchool.Tables)
+ {
+ Console.WriteLine(table.TableName);
+ ShowDataTable(table);
+ }
+
+ department.RejectChanges();
+ Console.WriteLine("After use the RejectChanges method in Department table to roll back the changes:");
+ ShowDataTable(department);
+
+ DataColumn[] primaryColumns = { course.Columns["CourseID"] };
+ DataColumn[] resetColumns = { course.Columns["Title"] };
+ ResetCourse(course, settings.MySchoolConnectionString, primaryColumns, resetColumns);
+ Console.WriteLine("After use the ResetCourse method in Course table to roll back the changes:");
+ ShowDataTable(course);
+
+ // Batch update the table.
+ String insertString = @"Insert into [MySchool].[dbo].[Course]([CourseID],[Year],[Title],
+ [Credits],[DepartmentID])
+ values (@CourseID,@Year,@Title,@Credits,@DepartmentID)";
+ SqlCommand insertCommand = new SqlCommand(insertString);
+ insertCommand.Parameters.Add("@CourseID", SqlDbType.NVarChar, 10, "CourseID");
+ insertCommand.Parameters.Add("@Year", SqlDbType.SmallInt, 2, "Year");
+ insertCommand.Parameters.Add("@Title", SqlDbType.NVarChar, 100, "Title");
+ insertCommand.Parameters.Add("@Credits", SqlDbType.Int, 4, "Credits");
+ insertCommand.Parameters.Add("@DepartmentID", SqlDbType.Int, 4, "DepartmentID");
+
+ const Int32 batchSize = 10;
+ BatchInsertUpdate(course, settings.MySchoolConnectionString, insertCommand, batchSize);
+ }
+
+ private static void CopyData(DataSet dataSet, String connectionString, SqlCommand selectCommand, DataTableMapping[] tableMappings)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ selectCommand.Connection = connection;
+
+ connection.Open();
+
+ using (SqlDataAdapter adapter = new SqlDataAdapter(selectCommand))
+ {
+ adapter.TableMappings.AddRange(tableMappings);
+ // If set the AcceptChangesDuringFill as the false, AcceptChanges will not be called on a
+ // DataRow after it is added to the DataTable during any of the Fill operations.
+ adapter.AcceptChangesDuringFill = false;
+
+ adapter.Fill(dataSet);
+ }
+ }
+ }
+
+ // Roll back only one column or several columns data of the Course table by call ResetDataTable method.
+ private static void ResetCourse(DataTable table, String connectionString,
+ DataColumn[] primaryColumns, DataColumn[] resetColumns)
+ {
+ table.PrimaryKey = primaryColumns;
+
+ // Build the query string
+ String primaryCols = String.Join(",", primaryColumns.Select(col => col.ColumnName));
+ String resetCols = String.Join(",", resetColumns.Select(col => $"Max({col.ColumnName}) as {col.ColumnName}"));
+
+ String selectString = $"Select {primaryCols},{resetCols} from Course Group by {primaryCols}";
+
+ SqlCommand selectCommand = new SqlCommand(selectString);
+
+ ResetDataTable(table, connectionString, selectCommand);
+ }
+
+ // RejectChanges will roll back all changes made to the table since it was loaded, or the last time AcceptChanges
+ // was called. When you copy from the database, you can lose all the data after calling RejectChanges
+ // The ResetDataTable method rolls back one or more columns of data.
+ private static void ResetDataTable(DataTable table, String connectionString,
+ SqlCommand selectCommand)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ selectCommand.Connection = connection;
+
+ connection.Open();
+
+ using (SqlDataAdapter adapter = new SqlDataAdapter(selectCommand))
+ {
+ // The incoming values for this row will be written to the current version of each
+ // column. The original version of each column's data will not be changed.
+ adapter.FillLoadOption = LoadOption.Upsert;
+
+ adapter.Fill(table);
+ }
+ }
+ }
+
+ private static void BatchInsertUpdate(DataTable table, String connectionString,
+ SqlCommand insertCommand, Int32 batchSize)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ insertCommand.Connection = connection;
+ // When setting UpdateBatchSize to a value other than 1, all the commands
+ // associated with the SqlDataAdapter have to have their UpdatedRowSource
+ // property set to None or OutputParameters. An exception is thrown otherwise.
+ insertCommand.UpdatedRowSource = UpdateRowSource.None;
+
+ connection.Open();
+
+ using (SqlDataAdapter adapter = new SqlDataAdapter())
+ {
+ adapter.InsertCommand = insertCommand;
+ // Gets or sets the number of rows that are processed in each round-trip to the server.
+ // Setting it to 1 disables batch updates, as rows are sent one at a time.
+ adapter.UpdateBatchSize = batchSize;
+
+ adapter.Update(table);
+
+ Console.WriteLine("Successfully to update the table.");
+ }
+ }
+ }
+
+ private static void ShowDataTable(DataTable table)
+ {
+ foreach (DataColumn col in table.Columns)
+ {
+ Console.Write("{0,-14}", col.ColumnName);
+ }
+ Console.WriteLine("{0,-14}", "RowState");
+
+ foreach (DataRow row in table.Rows)
+ {
+ foreach (DataColumn col in table.Columns)
+ {
+ if (col.DataType.Equals(typeof(DateTime)))
+ Console.Write("{0,-14:d}", row[col]);
+ else if (col.DataType.Equals(typeof(Decimal)))
+ Console.Write("{0,-14:C}", row[col]);
+ else
+ Console.Write("{0,-14}", row[col]);
+ }
+ Console.WriteLine("{0,-14}", row.RowState);
+ }
+ }
+}
+
+namespace CSDataAdapterOperations.Properties
+{
+ internal sealed partial class Settings : System.Configuration.ApplicationSettingsBase
+ {
+ private static readonly Settings defaultInstance =
+ ((Settings)(System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default => defaultInstance;
+
+ [System.Configuration.ApplicationScopedSetting()]
+ [System.Configuration.DefaultSettingValue("Data Source=(local);Initial Catalog=MySchool;Integrated Security=True")]
+ public string MySchoolConnectionString => ((string)(this["MySchoolConnectionString"]));
+ }
+}
+//
diff --git a/doc/samples/SqlDataAdapter_RetrieveIdentityStoredProcedure.cs b/doc/samples/SqlDataAdapter_RetrieveIdentityStoredProcedure.cs
new file mode 100644
index 0000000000..976de4e3b1
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_RetrieveIdentityStoredProcedure.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main()
+ {
+ string connectionString = GetConnectionString();
+ RetrieveIdentity(connectionString);
+ Console.ReadLine();
+ }
+
+ //
+ private static void RetrieveIdentity(string connectionString)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ // Create a SqlDataAdapter based on a SELECT query.
+ SqlDataAdapter adapter = new SqlDataAdapter(
+ "SELECT CategoryID, CategoryName FROM dbo.Categories",
+ connection);
+
+ //Create the SqlCommand to execute the stored procedure.
+ adapter.InsertCommand = new SqlCommand("dbo.InsertCategory",
+ connection);
+ adapter.InsertCommand.CommandType = CommandType.StoredProcedure;
+
+ // Add the parameter for the CategoryName. Specifying the
+ // ParameterDirection for an input parameter is not required.
+ adapter.InsertCommand.Parameters.Add(
+ new SqlParameter("@CategoryName", SqlDbType.NVarChar, 15,
+ "CategoryName"));
+
+ // Add the SqlParameter to retrieve the new identity value.
+ // Specify the ParameterDirection as Output.
+ SqlParameter parameter =
+ adapter.InsertCommand.Parameters.Add(
+ "@Identity", SqlDbType.Int, 0, "CategoryID");
+ parameter.Direction = ParameterDirection.Output;
+
+ // Create a DataTable and fill it.
+ DataTable categories = new DataTable();
+ adapter.Fill(categories);
+
+ // Add a new row.
+ DataRow newRow = categories.NewRow();
+ newRow["CategoryName"] = "New Category";
+ categories.Rows.Add(newRow);
+
+ adapter.Update(categories);
+
+ Console.WriteLine("List All Rows:");
+ foreach (DataRow row in categories.Rows)
+ {
+ {
+ Console.WriteLine("{0}: {1}", row[0], row[1]);
+ }
+ }
+ }
+ }
+ //
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=true";
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_SPIdentityReturn.cs b/doc/samples/SqlDataAdapter_SPIdentityReturn.cs
new file mode 100644
index 0000000000..41628b5478
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_SPIdentityReturn.cs
@@ -0,0 +1,70 @@
+//
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main()
+ {
+ string connectionString = GetConnectionString();
+ ReturnIdentity(connectionString);
+ // Console.ReadLine();
+ }
+
+ private static void ReturnIdentity(string connectionString)
+ {
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ // Create a SqlDataAdapter based on a SELECT query.
+ SqlDataAdapter adapter = new SqlDataAdapter(
+ "SELECT CategoryID, CategoryName FROM dbo.Categories", connection);
+
+ // Create a SqlCommand to execute the stored procedure.
+ adapter.InsertCommand = new SqlCommand("InsertCategory", connection);
+ adapter.InsertCommand.CommandType = CommandType.StoredProcedure;
+
+ // Create a parameter for the ReturnValue.
+ SqlParameter parameter = adapter.InsertCommand.Parameters.Add("@RowCount", SqlDbType.Int);
+ parameter.Direction = ParameterDirection.ReturnValue;
+
+ // Create an input parameter for the CategoryName.
+ // You do not need to specify direction for input parameters.
+ adapter.InsertCommand.Parameters.Add("@CategoryName", SqlDbType.NChar, 15, "CategoryName");
+
+ // Create an output parameter for the new identity value.
+ parameter = adapter.InsertCommand.Parameters.Add("@Identity", SqlDbType.Int, 0, "CategoryID");
+ parameter.Direction = ParameterDirection.Output;
+
+ // Create a DataTable and fill it.
+ DataTable categories = new DataTable();
+ adapter.Fill(categories);
+
+ // Add a new row.
+ DataRow categoryRow = categories.NewRow();
+ categoryRow["CategoryName"] = "New Beverages";
+ categories.Rows.Add(categoryRow);
+
+ // Update the database.
+ adapter.Update(categories);
+
+ // Retrieve the ReturnValue.
+ Int rowCount = (Int)adapter.InsertCommand.Parameters["@RowCount"].Value;
+
+ Console.WriteLine("ReturnValue: {0}", rowCount.ToString());
+ Console.WriteLine("All Rows:");
+ foreach (DataRow row in categories.Rows)
+ {
+ Console.WriteLine(" {0}: {1}", row[0], row[1]);
+ }
+ }
+ }
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;Integrated Security=true";
+ }
+}
+//
diff --git a/doc/samples/SqlDataAdapter_SqlDataAdapter.cs b/doc/samples/SqlDataAdapter_SqlDataAdapter.cs
index beb2486cbd..f48edacc8a 100644
--- a/doc/samples/SqlDataAdapter_SqlDataAdapter.cs
+++ b/doc/samples/SqlDataAdapter_SqlDataAdapter.cs
@@ -1,6 +1,5 @@
using System;
using System.Data;
-//
using Microsoft.Data.SqlClient;
class Program
@@ -8,8 +7,10 @@ class Program
static void Main()
{
}
+ //
public static SqlDataAdapter CreateSqlDataAdapter(SqlConnection connection)
{
+ // Assumes that connection is a valid SqlConnection object
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
@@ -45,5 +46,19 @@ public static SqlDataAdapter CreateSqlDataAdapter(SqlConnection connection)
return adapter;
}
+ //
+
+ public static SqlDataAdapter CustomerUpdateCommand(SqlDataAdapter adapter)
+ {
+ //
+ // Assumes that connection is a valid SqlAdapter object
+ adapter.UpdateCommand.Parameters.Add("@CompanyName",
+ SqlDbType.VarChar, 15, "CompanyName");
+ SqlParameter parameter = adapter.UpdateCommand.Parameters.Add("@CustomerID",
+ SqlDbType.Char, 5, "CustomerID");
+ parameter.SourceVersion = DataRowVersion.Original;
+ //
+ return adapter;
+ }
+
}
-//
diff --git a/doc/samples/SqlDataAdapter_TableMappings.cs b/doc/samples/SqlDataAdapter_TableMappings.cs
new file mode 100644
index 0000000000..4f2fc112e3
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_TableMappings.cs
@@ -0,0 +1,98 @@
+using System;
+using Microsoft.Data.SqlClient;
+using System.Data;
+using System.Data.Common;
+
+namespace DataAdapterTest
+{
+ class Program
+ {
+ static void Main()
+ {
+ string s = GetConnectionString();
+ SqlConnection c = new SqlConnection(s);
+ CustomerTableMapping(c);
+ BizTableMapping(c);
+ GetCustomersOrders(c);
+ Console.ReadLine();
+ }
+
+ static DataSet CustomerTableMapping(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object.
+ DataSet custDataSet = new DataSet();
+
+ SqlDataAdapter custAdapter = new SqlDataAdapter(
+ "SELECT * FROM dbo.Customers", connection);
+
+ DataTableMapping mapping =
+ custAdapter.TableMappings.Add("Table", "NorthwindCustomers");
+ mapping.ColumnMappings.Add("CompanyName", "Company");
+ mapping.ColumnMappings.Add("ContactName", "Contact");
+ mapping.ColumnMappings.Add("PostalCode", "ZIPCode");
+
+ custAdapter.Fill(custDataSet);
+ //
+
+ return custDataSet;
+ }
+ }
+
+ static DataSet BizTableMapping(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object.
+ DataSet custDataSet = new DataSet();
+
+ SqlDataAdapter custAdapter = new SqlDataAdapter(
+ "SELECT * FROM dbo.Customers", connection);
+
+ // The DataTableMapping is implemented ITableMapping.
+ ITableMapping mapping =
+ custAdapter.TableMappings.Add("Table", "BizTalkSchema");
+ mapping.ColumnMappings.Add("CustomerID", "ClientID");
+ mapping.ColumnMappings.Add("CompanyName", "ClientName");
+ mapping.ColumnMappings.Add("ContactName", "Contact");
+ mapping.ColumnMappings.Add("PostalCode", "ZIP");
+
+ custAdapter.Fill(custDataSet);
+ //
+
+ return custDataSet;
+ }
+ }
+
+ static DataSet GetCustomersOrders(SqlConnection connection)
+ {
+ using (connection)
+ {
+ //
+ // Assumes that connection is a valid SqlConnection object.
+ string queryString =
+ "SELECT * FROM dbo.Customers; SELECT * FROM dbo.Orders;";
+ SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
+
+ DataSet customersDataSet = new DataSet();
+
+ adapter.TableMappings.Add("Customers1", "Orders");
+ adapter.Fill(customersDataSet, "Customers");
+ //
+
+ return customersDataSet;
+ }
+ }
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataAdapter_Update.cs b/doc/samples/SqlDataAdapter_Update.cs
new file mode 100644
index 0000000000..9b1e194bd1
--- /dev/null
+++ b/doc/samples/SqlDataAdapter_Update.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Data;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main()
+ {
+ string connectionString = GetConnectionString();
+ AdapterUpdate(connectionString);
+ Console.ReadLine();
+ }
+ //
+ private static void AdapterUpdate(string connectionString)
+ {
+ using (SqlConnection connection =
+ new SqlConnection(connectionString))
+ {
+ SqlDataAdapter dataAdpater = new SqlDataAdapter(
+ "SELECT CategoryID, CategoryName FROM Categories",
+ connection);
+
+ dataAdpater.UpdateCommand = new SqlCommand(
+ "UPDATE Categories SET CategoryName = @CategoryName " +
+ "WHERE CategoryID = @CategoryID", connection);
+
+ dataAdpater.UpdateCommand.Parameters.Add(
+ "@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
+
+ SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
+ "@CategoryID", SqlDbType.Int);
+ parameter.SourceColumn = "CategoryID";
+ parameter.SourceVersion = DataRowVersion.Original;
+
+ DataTable categoryTable = new DataTable();
+ dataAdpater.Fill(categoryTable);
+
+ DataRow categoryRow = categoryTable.Rows[0];
+ categoryRow["CategoryName"] = "New Beverages";
+
+ dataAdpater.Update(categoryTable);
+
+ Console.WriteLine("Rows after update.");
+ foreach (DataRow row in categoryTable.Rows)
+ {
+ {
+ Console.WriteLine("{0}: {1}", row[0], row[1]);
+ }
+ }
+ }
+ }
+ //
+
+ static void UpdateCustomers(DataSet dataSet, SqlDataAdapter adapter)
+ {
+ //
+ // Assumes that dataSet and adapter are valid objects.
+ DataTable table = dataSet.Tables["Customers"];
+
+ // First process deletes.
+ adapter.Update(table.Select(null, null, DataViewRowState.Deleted));
+
+ // Next process updates.
+ adapter.Update(table.Select(null, null,
+ DataViewRowState.ModifiedCurrent));
+
+ // Finally, process inserts.
+ adapter.Update(table.Select(null, null, DataViewRowState.Added));
+ //
+ }
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=true";
+ }
+}
diff --git a/doc/samples/SqlDataReader_DataDiscoveryAndClassification.cs b/doc/samples/SqlDataReader_DataDiscoveryAndClassification.cs
index d9dfcee124..352cb20fe9 100644
--- a/doc/samples/SqlDataReader_DataDiscoveryAndClassification.cs
+++ b/doc/samples/SqlDataReader_DataDiscoveryAndClassification.cs
@@ -24,8 +24,9 @@ public static void Main()
if (DataClassificationSupported(connection))
{
// Create the temporary table and retrieve its Data Discovery and Classification information.
- CreateTable(connection);
- RunTests(connection);
+ // Set rankEnabled to be true if testing with rank information.
+ CreateTable(connection, rankEnabled : true);
+ RunTests(connection, rankEnabled : true);
}
}
finally
@@ -65,7 +66,8 @@ public static bool DataClassificationSupported(SqlConnection connection)
/// Creates a temporary table for this sample program and sets tags for Sensitivity Classification.
///
/// The SqlConnection to work with.
- private static void CreateTable(SqlConnection connection)
+ /// True if rank information is enabled and false otherwise
+ private static void CreateTable(SqlConnection connection, bool rankEnabled = false)
{
SqlCommand command = new SqlCommand(null, connection);
@@ -81,35 +83,58 @@ private static void CreateTable(SqlConnection connection)
+ "[Fax] [nvarchar](30) MASKED WITH (FUNCTION = 'default()') NULL)";
command.ExecuteNonQuery();
- // Set Sensitivity Classification tags for table columns.
- command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
- + ".CompanyName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Company Name', INFORMATION_TYPE_ID='COMPANY')";
- command.ExecuteNonQuery();
+ if (rankEnabled)
+ {
+ // Set Sensitivity Classification tags for table columns with rank information
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".CompanyName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Company Name', INFORMATION_TYPE_ID='COMPANY', RANK=LOW)";
+ command.ExecuteNonQuery();
- command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
- + ".ContactName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Person Name', INFORMATION_TYPE_ID='NAME')";
- command.ExecuteNonQuery();
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".ContactName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Person Name', INFORMATION_TYPE_ID='NAME', RANK=LOW)";
+ command.ExecuteNonQuery();
- command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
- + ".Phone WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT')";
- command.ExecuteNonQuery();
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".Phone WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT', RANK=MEDIUM)";
+ command.ExecuteNonQuery();
- command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
- + ".Fax WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT')";
- command.ExecuteNonQuery();
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".Fax WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT', RANK=MEDIUM)";
+ command.ExecuteNonQuery();
+ }
+ else
+ {
+ // Set Sensitivity Classification tags for table columns without rank information
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".CompanyName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Company Name', INFORMATION_TYPE_ID='COMPANY')";
+ command.ExecuteNonQuery();
+
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".ContactName WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Person Name', INFORMATION_TYPE_ID='NAME')";
+ command.ExecuteNonQuery();
+
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".Phone WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT')";
+ command.ExecuteNonQuery();
+
+ command.CommandText = $"ADD SENSITIVITY CLASSIFICATION TO {tableName}"
+ + ".Fax WITH (LABEL='PII', LABEL_ID='L1', INFORMATION_TYPE='Contact Information', INFORMATION_TYPE_ID='CONTACT')";
+ command.ExecuteNonQuery();
+ }
}
///
/// Run query to fetch result set from target table.
///
/// The SqlConnection to work with.
- private static void RunTests(SqlConnection connection)
+ /// True if rank information is enabled and false otherwise
+ private static void RunTests(SqlConnection connection, bool rankEnabled = false)
{
SqlCommand command = new SqlCommand(null, connection);
command.CommandText = $"SELECT * FROM {tableName}";
using (SqlDataReader reader = command.ExecuteReader())
{
- PrintSensitivityClassification(reader);
+ PrintSensitivityClassification(reader, rankEnabled);
}
}
@@ -117,7 +142,8 @@ private static void RunTests(SqlConnection connection)
/// Prints Sensitivity Classification data as received in the result set.
///
/// The SqlDataReader to work with.
- private static void PrintSensitivityClassification(SqlDataReader reader)
+ /// True if rank information is enabled and false otherwise
+ private static void PrintSensitivityClassification(SqlDataReader reader, bool rankEnabled = false)
{
if (reader.SensitivityClassification != null)
{
@@ -140,8 +166,11 @@ private static void PrintSensitivityClassification(SqlDataReader reader)
Console.WriteLine($"Information Type: {sp.InformationType.Name}");
Console.WriteLine();
}
+
+ Console.WriteLine($"Sensitivity Rank: {sp.SensitivityRank.ToString()}");
}
}
+ Console.Writeline($"reader.SensitivityClassification.SensitivityRank : {reader.SensitivityClassification.SensitivityRank.ToString()}");
}
}
diff --git a/doc/samples/SqlDataReader_GetSchemaTable.cs b/doc/samples/SqlDataReader_GetSchemaTable.cs
new file mode 100644
index 0000000000..5f540ae5d9
--- /dev/null
+++ b/doc/samples/SqlDataReader_GetSchemaTable.cs
@@ -0,0 +1,54 @@
+using System;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace NextResultCS
+{
+ class Program
+ {
+ static void Main()
+ {
+ string s = GetConnectionString();
+ SqlConnection c = new SqlConnection(s);
+ GetSchemaInfo(c);
+ Console.ReadLine();
+ }
+ //
+ static void GetSchemaInfo(SqlConnection connection)
+ {
+ using (connection)
+ {
+ SqlCommand command = new SqlCommand(
+ "SELECT CategoryID, CategoryName FROM Categories;",
+ connection);
+ connection.Open();
+
+ SqlDataReader reader = command.ExecuteReader();
+
+ // Retrieve schema information about the current result-set.
+ DataTable schemaTable = reader.GetSchemaTable();
+
+ foreach (DataRow row in schemaTable.Rows)
+ {
+ foreach (DataColumn column in schemaTable.Columns)
+ {
+ Console.WriteLine(String.Format("{0} = {1}",
+ column.ColumnName, row[column]));
+ }
+ }
+
+ // Always call the Close method when you have finished using the DataReader object.
+ reader.Close();
+ }
+ }
+ //
+
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataReader_HasRows.cs b/doc/samples/SqlDataReader_HasRows.cs
new file mode 100644
index 0000000000..caeb01f1d6
--- /dev/null
+++ b/doc/samples/SqlDataReader_HasRows.cs
@@ -0,0 +1,57 @@
+using System;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace NextResultCS
+{
+ class Program
+ {
+ static void Main()
+ {
+ string s = GetConnectionString();
+ SqlConnection c = new SqlConnection(s);
+ HasRows(c);
+ Console.ReadLine();
+ }
+
+ //
+ static void HasRows(SqlConnection connection)
+ {
+ using (connection)
+ {
+ SqlCommand command = new SqlCommand(
+ "SELECT CategoryID, CategoryName FROM Categories;",
+ connection);
+ connection.Open();
+
+ SqlDataReader reader = command.ExecuteReader();
+
+ // Check if the DataReader has any row.
+ if (reader.HasRows)
+ {
+ // Obtain a row from the query result.
+ while (reader.Read())
+ {
+ Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
+ reader.GetString(1));
+ }
+ }
+ else
+ {
+ Console.WriteLine("No rows found.");
+ }
+ // Always call the Close method when you have finished using the DataReader object.
+ reader.Close();
+ }
+ }
+
+ //
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataReader_NextResult.cs b/doc/samples/SqlDataReader_NextResult.cs
new file mode 100644
index 0000000000..4dccf5a55f
--- /dev/null
+++ b/doc/samples/SqlDataReader_NextResult.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Data.SqlClient;
+using System.Data;
+
+namespace NextResultCS
+{
+ class Program
+ {
+ static void Main()
+ {
+ string s = GetConnectionString();
+ SqlConnection c = new SqlConnection(s);
+ RetrieveMultipleResults(c);
+ Console.ReadLine();
+ }
+
+ //
+ static void RetrieveMultipleResults(SqlConnection connection)
+ {
+ using (connection)
+ {
+ SqlCommand command = new SqlCommand(
+ "SELECT CategoryID, CategoryName FROM dbo.Categories;" +
+ "SELECT EmployeeID, LastName FROM dbo.Employees",
+ connection);
+ connection.Open();
+
+ SqlDataReader reader = command.ExecuteReader();
+
+ // Check if the DataReader has any row.
+ while (reader.HasRows)
+ {
+ Console.WriteLine("\t{0}\t{1}", reader.GetName(0),
+ reader.GetName(1));
+
+ // Obtain a row from the query result.
+ while (reader.Read())
+ {
+ Console.WriteLine("\t{0}\t{1}", reader.GetInt32(0),
+ reader.GetString(1));
+ }
+
+ // Hop to the next result-set.
+ reader.NextResult();
+ }
+ // Always call the Close method when you have finished using the DataReader object.
+ reader.Close();
+ }
+ }
+
+ //
+ static private string GetConnectionString()
+ {
+ // To avoid storing the connection string in your code,
+ // you can retrieve it from a configuration file.
+ return "Data Source=(local);Initial Catalog=Northwind;"
+ + "Integrated Security=SSPI";
+ }
+ }
+}
diff --git a/doc/samples/SqlDataSourceEnumeratorExample.cs b/doc/samples/SqlDataSourceEnumeratorExample.cs
new file mode 100644
index 0000000000..279881c672
--- /dev/null
+++ b/doc/samples/SqlDataSourceEnumeratorExample.cs
@@ -0,0 +1,33 @@
+using System;
+//
+using Microsoft.Data.Sql;
+
+class Program
+{
+ static void Main()
+ {
+ // Retrieve the enumerator instance and then the data.
+ SqlDataSourceEnumerator instance =
+ SqlDataSourceEnumerator.Instance;
+ System.Data.DataTable table = instance.GetDataSources();
+
+ // Display the contents of the table.
+ DisplayData(table);
+
+ Console.WriteLine("Press any key to continue.");
+ Console.ReadKey();
+ }
+
+ private static void DisplayData(System.Data.DataTable table)
+ {
+ foreach (System.Data.DataRow row in table.Rows)
+ {
+ foreach (System.Data.DataColumn col in table.Columns)
+ {
+ Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
+ }
+ Console.WriteLine("============================");
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlDataSourceEnumeratorVersionExample.cs b/doc/samples/SqlDataSourceEnumeratorVersionExample.cs
new file mode 100644
index 0000000000..73eefc1235
--- /dev/null
+++ b/doc/samples/SqlDataSourceEnumeratorVersionExample.cs
@@ -0,0 +1,25 @@
+using System;
+//
+using Microsoft.Data.Sql;
+
+class Program
+{
+ static void Main()
+ {
+ // Retrieve the enumerator instance, and
+ // then retrieve the data sources.
+ SqlDataSourceEnumerator instance =
+ SqlDataSourceEnumerator.Instance;
+ System.Data.DataTable table = instance.GetDataSources();
+
+ // Filter the sources to just show SQL Server 2012 instances.
+ System.Data.DataRow[] rows = table.Select("Version LIKE '11%'");
+ foreach (System.Data.DataRow row in rows)
+ {
+ Console.WriteLine(row["ServerName"]);
+ }
+ Console.WriteLine("Press any key to continue.");
+ Console.ReadKey();
+ }
+}
+//
diff --git a/doc/samples/SqlFunctionAttribute.cs b/doc/samples/SqlFunctionAttribute.cs
index 6f20986cf6..28a027caad 100644
--- a/doc/samples/SqlFunctionAttribute.cs
+++ b/doc/samples/SqlFunctionAttribute.cs
@@ -2,7 +2,7 @@
using System.IO;
using System.Collections;
//
-using Microsoft.Data.SqlClient.Server;
+using Microsoft.SqlServer.Server;
public class Class1
{
diff --git a/doc/samples/SqlTransactionLocal.cs b/doc/samples/SqlTransactionLocal.cs
new file mode 100644
index 0000000000..29d29526ab
--- /dev/null
+++ b/doc/samples/SqlTransactionLocal.cs
@@ -0,0 +1,57 @@
+//
+using System;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = AdventureWorks";
+
+ using (SqlConnection connection = new SqlConnection(connectionString))
+ {
+ connection.Open();
+
+ // Start a local transaction.
+ SqlTransaction sqlTran = connection.BeginTransaction();
+
+ // Enlist a command in the current transaction.
+ SqlCommand command = connection.CreateCommand();
+ command.Transaction = sqlTran;
+
+ try
+ {
+ // Execute two separate commands.
+ command.CommandText =
+ "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
+ command.ExecuteNonQuery();
+ command.CommandText =
+ "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
+ command.ExecuteNonQuery();
+
+ // Commit the transaction.
+ sqlTran.Commit();
+ Console.WriteLine("Both records were written to database.");
+ }
+ catch (Exception ex)
+ {
+ // Handle the exception if the transaction fails to commit.
+ Console.WriteLine(ex.Message);
+
+ try
+ {
+ // Attempt to roll back the transaction.
+ sqlTran.Rollback();
+ }
+ catch (Exception exRollback)
+ {
+ // Throws an InvalidOperationException if the connection
+ // is closed or the transaction has already been rolled
+ // back on the server.
+ Console.WriteLine(exRollback.Message);
+ }
+ }
+ }
+ }
+}
+//
diff --git a/doc/samples/SqlTransactionScope.cs b/doc/samples/SqlTransactionScope.cs
new file mode 100644
index 0000000000..77f5d75694
--- /dev/null
+++ b/doc/samples/SqlTransactionScope.cs
@@ -0,0 +1,99 @@
+//
+using System;
+using System.Transactions;
+using Microsoft.Data.SqlClient;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = AdventureWorks";
+
+ string commandText1 = "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
+ string commandText2 = "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
+
+ int result = CreateTransactionScope(connectionString, connectionString, commandText1, commandText2);
+
+ Console.WriteLine("result = " + result);
+ }
+
+ static public int CreateTransactionScope(string connectString1, string connectString2,
+ string commandText1, string commandText2)
+ {
+ // Initialize the return value to zero and create a StringWriter to display results.
+ int returnValue = 0;
+ System.IO.StringWriter writer = new System.IO.StringWriter();
+
+ // Create the TransactionScope in which to execute the commands, guaranteeing
+ // that both commands will commit or roll back as a single unit of work.
+ using (TransactionScope scope = new TransactionScope())
+ {
+ using (SqlConnection connection1 = new SqlConnection(connectString1))
+ {
+ try
+ {
+ // Opening the connection automatically enlists it in the
+ // TransactionScope as a lightweight transaction.
+ connection1.Open();
+
+ // Create the SqlCommand object and execute the first command.
+ SqlCommand command1 = new SqlCommand(commandText1, connection1);
+ returnValue = command1.ExecuteNonQuery();
+ writer.WriteLine("Rows to be affected by command1: {0}", returnValue);
+
+ // if you get here, this means that command1 succeeded. By nesting
+ // the using block for connection2 inside that of connection1, you
+ // conserve server and network resources by opening connection2
+ // only when there is a chance that the transaction can commit.
+ using (SqlConnection connection2 = new SqlConnection(connectString2))
+ try
+ {
+ // The transaction is promoted to a full distributed
+ // transaction when connection2 is opened.
+ connection2.Open();
+
+ // Execute the second command in the second database.
+ returnValue = 0;
+ SqlCommand command2 = new SqlCommand(commandText2, connection2);
+ returnValue = command2.ExecuteNonQuery();
+ writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
+ }
+ catch (Exception ex)
+ {
+ // Display information that command2 failed.
+ writer.WriteLine("returnValue for command2: {0}", returnValue);
+ writer.WriteLine("Exception Message2: {0}", ex.Message);
+ }
+ }
+ catch (Exception ex)
+ {
+ // Display information that command1 failed.
+ writer.WriteLine("returnValue for command1: {0}", returnValue);
+ writer.WriteLine("Exception Message1: {0}", ex.Message);
+ }
+ }
+
+ // If an exception has been thrown, Complete will not
+ // be called and the transaction is rolled back.
+ scope.Complete();
+ }
+
+ // The returnValue is greater than 0 if the transaction committed.
+ if (returnValue > 0)
+ {
+ writer.WriteLine("Transaction was committed.");
+ }
+ else
+ {
+ // You could write additional business logic here, notify the caller by
+ // throwing a TransactionAbortedException, or log the failure.
+ writer.WriteLine("Transaction rolled back.");
+ }
+
+ // Display messages.
+ Console.WriteLine(writer.ToString());
+
+ return returnValue;
+ }
+}
+//
diff --git a/doc/samples/SqlUserDefinedAggregate.cs b/doc/samples/SqlUserDefinedAggregate.cs
index 45a45dff7c..7f3792c133 100644
--- a/doc/samples/SqlUserDefinedAggregate.cs
+++ b/doc/samples/SqlUserDefinedAggregate.cs
@@ -1,20 +1,20 @@
using System;
//
-using Microsoft.Data.SqlClient.Server;
+using Microsoft.SqlServer.Server;
using System.IO;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Text;
[Serializable]
-[Microsoft.Data.SqlClient.Server.SqlUserDefinedAggregate(
- Microsoft.Data.SqlClient.Server.Format.UserDefined,
+[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(
+ Microsoft.SqlServer.Server.Format.UserDefined,
IsInvariantToNulls = true,
IsInvariantToDuplicates = false,
IsInvariantToOrder = false,
MaxByteSize = 8000)
]
-public class Concatenate : Microsoft.Data.SqlClient.Server.IBinarySerialize
+public class Concatenate : Microsoft.SqlServer.Server.IBinarySerialize
{
public void Read(BinaryReader r)
diff --git a/doc/samples/SqlUserDefinedType1.cs b/doc/samples/SqlUserDefinedType1.cs
index 5601a016b1..8f440648c2 100644
--- a/doc/samples/SqlUserDefinedType1.cs
+++ b/doc/samples/SqlUserDefinedType1.cs
@@ -2,7 +2,7 @@
//
using System;
using System.Data.SqlTypes;
-using Microsoft.Data.SqlClient.Server;
+using Microsoft.SqlServer.Server;
[Serializable()]
[SqlUserDefinedType(Format.Native)]
@@ -133,7 +133,7 @@ public SqlString Quadrant()
//-----------------------------------------------------------------------------
//
-// using Microsoft.Data.SqlClient.Server;
+// using Microsoft.SqlServer.Server;
[SqlUserDefinedType(Format.Native, MaxByteSize = 8000)]
public class SampleType
diff --git a/doc/samples/TransactionIsolationLevels.cs b/doc/samples/TransactionIsolationLevels.cs
index dc85d9447b..6abd99e15d 100644
--- a/doc/samples/TransactionIsolationLevels.cs
+++ b/doc/samples/TransactionIsolationLevels.cs
@@ -487,7 +487,7 @@ class TransactionIsolationLevelsProgram
{
internal static void Main(string[] args)
{
- String connString = "Data Source=(local);Initial Catalog=master;Integrated Security=True;Asynchronous Processing=true;";
+ String connString = "Data Source=(local);Initial Catalog=master;Integrated Security=True;";
OperateDatabase.CreateDatabase(connString);
Console.WriteLine();
diff --git a/doc/snippets/Microsoft.Data.Sql/SqlDataSourceEnumerator.xml b/doc/snippets/Microsoft.Data.Sql/SqlDataSourceEnumerator.xml
new file mode 100644
index 0000000000..55e1f2c057
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.Sql/SqlDataSourceEnumerator.xml
@@ -0,0 +1,65 @@
+
+
+
+
+ Provides a mechanism for enumerating all available instances of SQL Server within the local network.
+
+ class exposes this information to the application developer, providing a containing information about all the available servers. This returned table contains a list of server instances that matches the list provided when a user attempts to create a new connection, and on the `Connection Properties` dialog box, expands the drop-down list containing all the available servers.
+
+ ]]>
+
+ Enumerating Instances of SQL Server
+
+
+ Retrieves a containing information about all visible SQL Server instances.
+ A containing information about the visible SQL Server instances.
+
+ 10.0.xx for SQL Server 2008 10.50.x for SQL Server 2008 R2 11.0.xx for SQL Server 2012 12.0.xx for SQL Server 2014 13.0.xx for SQL Server 2016 14.0.xx for SQL Server 2017|
+
+> [!NOTE]
+> Due to the nature of the mechanism used by to locate data sources on a network, the method will not always return a complete list of the available servers, and the list might not be the same on every call. If you plan to use this function to let users select a server from a list, make sure that you always also supply an option to type in a name that is not in the list, in case the server enumeration does not return all the available servers. In addition, this method may take a significant amount of time to execute, so be careful about calling it when performance is critical.
+
+## Examples
+ The following console application retrieves information about all the visible SQL Server instances and displays the information in the console window.
+
+[!code-csharp[SqlDataSourceEnumerator.Example#1](~/../sqlclient/doc/samples/SqlDataSourceEnumeratorExample.cs#1)]
+
+ ]]>
+
+ Enumerating Instances of SQL Server
+
+
+ Gets an instance of the , which can be used to retrieve information about available SQL Server instances.
+ An instance of the used to retrieve information about available SQL Server instances.
+
+ class does not provide a constructor. Use the property to retrieve an instance of the class instead.
+
+[!code-csharp[SqlDataSourceEnumeratorExample#1](~/../sqlclient/doc/samples/SqlDataSourceEnumeratorExample.cs#1)]
+
+## Examples
+The following console application displays a list of all the available SQL Server 2005 instances within the local network. This code uses the method to filter the rows in the table returned by the method.
+ [!code-csharp[SqlDataSourceEnumeratorVersionExample#1](~/../sqlclient/doc/samples/SqlDataSourceEnumeratorVersionExample.cs#1)]
+
+ ]]>
+
+ Enumerating Instances of SQL Server
+
+
+
+
diff --git a/doc/snippets/Microsoft.Data.Sql/SqlNotificationRequest.xml b/doc/snippets/Microsoft.Data.Sql/SqlNotificationRequest.xml
index 4c3f6bd5f9..8a60e5c16c 100644
--- a/doc/snippets/Microsoft.Data.Sql/SqlNotificationRequest.xml
+++ b/doc/snippets/Microsoft.Data.Sql/SqlNotificationRequest.xml
@@ -11,7 +11,7 @@ This class provides low-level access to the query notification services exposed
]]>
- Using Query Notifications
+ Using Query NotificationsCreates a new instance of the class with default values.
@@ -23,7 +23,7 @@ If the parameterless constructor is used to create a
- Using Query Notifications
+ Using Query Notifications
A string that contains an application-specific identifier for this notification. It is not used by the notifications infrastructure, but it allows you to associate notifications with the application state. The value indicated in this parameter is included in the Service Broker queue message.
@@ -40,7 +40,7 @@ This constructor allows you to initialize a new The value of the parameter is NULL.The or parameter is longer than or the value in the parameter is less than zero.
- Using Query Notifications
+ Using Query NotificationsGets or sets the SQL Server Service Broker service name where notification messages are posted.
@@ -64,7 +64,7 @@ The SQL Server Service Broker service must be previously configured on the serve
The value is NULL.The value is longer than .
- Using Query Notifications
+ Using Query NotificationsGets or sets a value that specifies how long SQL Server waits for a change to occur before the operation times out.
@@ -78,7 +78,7 @@ After the time-out period expires, the notification is sent even if no change ta
]]>
The value is less than zero.
- Using Query Notifications
+ Using Query NotificationsGets or sets an application-specific identifier for this notification.
@@ -92,7 +92,7 @@ This value is not used by the notifications infrastructure. Instead, it is a mec
]]>
The value is longer than .
- Using Query Notifications
+ Using Query Notifications
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/DataAccessKind.xml b/doc/snippets/Microsoft.Data.SqlClient.Server/DataAccessKind.xml
deleted file mode 100644
index d429e11dd9..0000000000
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/DataAccessKind.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
- Describes the type of access to user data for a user-defined method or function.
-
- and to indicate whether the method or function uses ADO.NET to connect back to the database using the "context connection."
-
- Note that methods and functions are not allowed to make changes to the database, so the options for this enumeration are `None` (meaning no data-access performed by the method or function) and `Read` (meaning that the method or function perform read-only data-access operations, such as executing SELECT statements).
-
- ]]>
-
-
-
- The method or function does not access user data.
-
-
- The method or function reads user data.
-
-
-
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/IBinarySerialize.xml b/doc/snippets/Microsoft.Data.SqlClient.Server/IBinarySerialize.xml
deleted file mode 100644
index a84e479859..0000000000
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/IBinarySerialize.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
- Provides custom implementation for user-defined type (UDT) and user-defined aggregate serialization and deserialization.
-
- .`Native` or .`UserDefined`.
-
- .`Native` allows SQL Server to handle serialization and deserialization automatically, but the format has restrictions on the kind of types it can handle. .`UserDefined` allows user-defined types and aggregates to handle their own serialization. User-defined types and aggregates must be marked with .`UserDefined` in the `SqlUserDefinedType` or `SqlUserDefinedAggregate` attribute, and must implement the interface.
-
- Note that even with custom serialization, the total size of each instance must be under the maximum allowed limit, currently 8000 bytes.
-
- ]]>
-
-
-
- The stream from which the object is deserialized.
- Generates a user-defined type (UDT) or user-defined aggregate from its binary form.
-
- method must reconstitute your object using the information written by the method.
-
-## Examples
- The following example shows the implementation of the method of a UDT, which uses a to de-serialize a previously persisted UDT. This example assumes that the UDT has two data properties: `StringValue` and `DoubleValue`.
-
- [!code-csharp[IBinarySerialize Samples#1](~/../sqlclient/doc/samples/IBinarySerialize.cs#1)]
-
- ]]>
-
-
-
- The stream to which the UDT or user-defined aggregate is serialized.
- Converts a user-defined type (UDT) or user-defined aggregate into its binary format so that it may be persisted.
-
- method to reconstitute your UDT or user-defined aggregate.
-
-## Examples
- The following example shows the implementation of the method of a UDT, which uses a to serialize the UDT in the user-defined binary format. The purpose of the null character padding is to ensure that the string value is completely separated from the double value, so that one UDT is compared to another in Transact-SQL code, string bytes are compared to string bytes and double bytes are compared to double bytes.
-
- [!code-csharp[IBinarySerialize Samples#2](~/../sqlclient/doc/samples/IBinarySerialize.cs#2)]
-
- ]]>
-
-
-
-
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/InvalidUdtException.xml b/doc/snippets/Microsoft.Data.SqlClient.Server/InvalidUdtException.xml
deleted file mode 100644
index 70bfd160f4..0000000000
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/InvalidUdtException.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- Thrown when SQL Server or the ADO.NET provider detects an invalid user-defined type (UDT).
- To be added.
-
-
- The object.
- The object.
- Streams all the properties into the class for the given .
-
- class to make the class serializable.
-
- ]]>
-
-
-
-
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml b/doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml
index cb89fe35a0..a2481e9363 100644
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient.Server/SqlDataRecord.xml
@@ -2,7 +2,7 @@
- Represents a single row of data and its metadata. This class cannot be inherited.
+ Represents a single row of data and its metadata.
@@ -236,7 +236,7 @@ For more information, see [Table-Valued Parameters](/dotnet/framework/data/adone
@@ -255,7 +255,7 @@ For more information, see [Table-Valued Parameters](/dotnet/framework/data/adone
@@ -321,7 +321,7 @@ The following are the default values assigned to `dbType`, depending on the `Sql
@@ -341,7 +341,7 @@ For more information, see [Table-Valued Parameters](/dotnet/framework/data/adone
@@ -361,7 +361,7 @@ For more information, see [Table-Valued Parameters](/dotnet/framework/data/adone
@@ -384,7 +384,7 @@ For more information, see [Table-Valued Parameters](/dotnet/framework/data/adone
@@ -692,7 +692,7 @@ The default is `FALSE`.
This property can only be set in one of the constructors.
-For more information, see [Table-Valued Parameters](/dotnet/framework/data/adonet/sql/table-valued-parameters).
+For more information, see [Table-Valued Parameters](/sql/connect/ado-net/sql/table-valued-parameters).
]]>
@@ -777,7 +777,7 @@ Returns 0 if the scale of the underlying column type is not defined.
## Remarks
This property can only be set in one of the constructors.
-For more information, see [Table-Valued Parameters](/dotnet/framework/data/adonet/sql/table-valued-parameters).
+For more information, see [Table-Valued Parameters](/sql/connect/ado-net/sql/table-valued-parameters).
]]>
@@ -793,7 +793,7 @@ The default is 1.
This property can only be set in one of the constructors.
-For more information, see [Table-Valued Parameters](/dotnet/framework/data/adonet/sql/table-valued-parameters).
+For more information, see [Table-Valued Parameters](/sql/connect/ado-net/sql/table-valued-parameters).
]]>
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlUserDefinedTypeAttribute.xml b/doc/snippets/Microsoft.Data.SqlClient.Server/SqlUserDefinedTypeAttribute.xml
deleted file mode 100644
index 14bc23a2bd..0000000000
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlUserDefinedTypeAttribute.xml
+++ /dev/null
@@ -1,137 +0,0 @@
-
-
-
-
- Used to mark a type definition in an assembly as a user-defined type (UDT) in SQL Server. The properties on the attribute reflect the physical characteristics used when the type is registered with SQL Server. This class cannot be inherited.
-
- custom attribute. Every UDT must be annotated with this attribute. See [CLR User-Defined Types](https://go.microsoft.com/fwlink/?LinkId=128028) for more information about UDTs, including an example of a UDT.
-
-## Examples
-The following example shows the `UserDefinedType` attribute of the Point UDT. The UDT is byte-ordered, is named "Point", has a validation method named "ValidatePoint", and uses the native serialization format.
-
-[!code-csharp[SqlUserDefinedType Example#1](~/../sqlclient/doc/samples/SqlUserDefinedType.cs#1)]
-
-]]>
-
-
-
- One of the values representing the serialization format of the type.
- A required attribute on a user-defined type (UDT), used to confirm that the given type is a UDT and to indicate the storage format of the UDT.
-
-
-
-
-
- The serialization format as a .
- A value representing the serialization format.
-
-
- Indicates whether the user-defined type is byte ordered.
-
- if the user-defined type is byte ordered; otherwise .
-
- property in effect guarantees that the serialized binary data can be used for semantic ordering of the information. Thus, each instance of a byte-ordered UDT object can only have one serialized representation. When a comparison operation is performed in SQL Server on the serialized bytes, its results should be the same as if the same comparison operation had taken place in managed code.
-
-The following features are supported when is set to `true`:
-
-- The ability to create indexes on columns of this type.
-
-- The ability to create primary and foreign keys as well as CHECK and UNIQUE constraints on columns of this type.
-
-- The ability to use Transact-SQL ORDER BY, GROUP BY, and PARTITION BY clauses. In these cases, the binary representation of the type is used to determine the order.
-
-- The ability to use comparison operators in Transact-SQL statements.
-
-- The ability to persist computed columns of this type.
-
-Note that both the `Native` and `UserDefined` serialization formats support the following comparison operators when is set to `true`:
-
-- Equal to (=)
-
-- Not equal to (!=)
-
-- Greater than (>)
-
-- Less than (\<)
-
-- Greater than or equal to (>=)
-
-- Less than or equal to (<=)
-
-]]>
-
-
-
- Indicates whether all instances of this user-defined type are the same length.
-
- if all instances of this type are the same length; otherwise .
-
-
- . This attribute is only relevant for UDTs with `UserDefined` serialization .
-
-]]>
-
-
-
- The maximum size of the instance, in bytes.
- An value representing the maximum size of the instance.
-
- property with the `UserDefined` serialization .
-
-When connecting to SQL Server 2005 or earlier, must be between 1 and 8000.
-
-When connecting to SQL Server 2008 or later, set between 1 and 8000, for a type whose instances are always 8,000 bytes or less. For types that can have instances larger than 8000, specify -1.
-
-For a UDT with user-defined serialization specified, refers to the total size of the UDT in its serialized form as defined by the user. Consider a UDT with a property of a string of 10 characters (). When the UDT is serialized using a , the total size of the serialized string is 22 bytes: 2 bytes per Unicode UTF-16 character, multiplied by the maximum number of characters, plus 2 control bytes of overhead incurred from serializing a binary stream. So, when determining the value of , the total size of the serialized UDT must be considered: the size of the data serialized in binary form plus the overhead incurred by serialization.
-
-This property should not be used with `Native` serialization .
-
-]]>
-
-
-
- The SQL Server name of the user-defined type.
- A value representing the SQL Server name of the user-defined type.
-
- property is not used within SQL Server, but is used by the Microsoft Visual Studio .NET Integrated Development Environment (IDE).
-
-]]>
-
-
-
- The name of the method used to validate instances of the user-defined type.
- A representing the name of the method used to validate instances of the user-defined type.
-
-
-
-
-
-
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/SystemDataAccessKind.xml b/doc/snippets/Microsoft.Data.SqlClient.Server/SystemDataAccessKind.xml
deleted file mode 100644
index e2209278d7..0000000000
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/SystemDataAccessKind.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
- Describes the type of access to system data for a user-defined method or function.
-
- and to indicate what type of access to system data the method or function has.
-
- Note that methods and functions are not allowed to make changes to the database, so the options for this enumeration are `None` (meaning no data-access performed by the method or function) and `Read` (meaning that the method or function performs read-only data-access operations, such as executing SELECT statements).
-
- ]]>
-
-
-
- The method or function does not access system data.
-
-
- The method or function reads system data.
-
-
-
diff --git a/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml
index 081e22dcd6..5a69be7478 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/ActiveDirectoryAuthenticationProvider.xml
@@ -95,13 +95,16 @@ The following example demonstrates providing a custom device flow callback to Sq
are:
+ The supported authentication modes with are:
- Active Directory Password
- Active Directory Integrated
- Active Directory Interactive
- Active Directory Service Principal
- Active Directory Device Code Flow
+- Active Directory Managed Identity
+- Active Directory MSI
+- Active Directory Default
]]>
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationMethod.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationMethod.xml
index 19927484fd..a52a2ec41a 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationMethod.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationMethod.xml
@@ -34,12 +34,16 @@
6
- The authentication method uses Active Directory Managed Identity. Use System Assigned or User Assigned Managed Identity to connect to SQL Database from Azure client environments that have enabled support for Managed Identity. For User Assigned Managed Identity, 'User Id' or 'UID' is required to be set to the object ID of the user identity.
+ The authentication method uses Active Directory Managed Identity. Use System Assigned or User Assigned Managed Identity to connect to SQL Database from Azure client environments that have enabled support for Managed Identity. For User Assigned Managed Identity, 'User Id' or 'UID' is required to be set to the "client ID" of the user identity.7
- Alias for "Active Directory Managed Identity" authentication method. Use System Assigned or User Assigned Managed Identity to connect to SQL Database from Azure client environments that have enabled support for Managed Identity. For User Assigned Managed Identity, 'User Id' or 'UID' is required to be set to the object ID of the user identity.
+ Alias for "Active Directory Managed Identity" authentication method. Use System Assigned or User Assigned Managed Identity to connect to SQL Database from Azure client environments that have enabled support for Managed Identity. For User Assigned Managed Identity, 'User Id' or 'UID' is required to be set to the "client ID" of the user identity.8
+
+ The authentication method uses Active Directory Default. Use this mode to connect to a SQL Database using multiple non-interactive authentication methods tried sequentially to acquire an access token. This method does not fallback to the "Active Directory Interactive" authentication method.
+ 9
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationParameters.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationParameters.xml
index 520882eb93..51fec0ae1f 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationParameters.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlAuthenticationParameters.xml
@@ -12,7 +12,8 @@
The user login name/ID.
The user password.
The connection ID.
- Initializes a new instance of the class using the specified authentication method, server name, database name, resource URI, authority URI, user login name/ID, user password and connection ID.
+ The connection timeout value in seconds.
+ Initializes a new instance of the class using the specified authentication method, server name, database name, resource URI, authority URI, user login name/ID, user password, connection ID and connection timeout value.Gets the authentication method.
@@ -46,5 +47,9 @@
Gets the database name.The database name.
+
+ Gets the connection timeout value.
+ The connection timeout value to be passed to Cancellation Token Source.
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml
index 6247136669..d7299c5e80 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopy.xml
@@ -8,14 +8,14 @@
class lets you write managed code solutions that provide similar functionality. There are other ways to load data into a SQL Server table (INSERT statements, for example), but offers a significant performance advantage over them. The class can be used to write data only to SQL Server tables. However, the data source is not limited to SQL Server; any data source can be used, as long as the data can be loaded to a instance or read with a instance. will fail when bulk loading a column of type into a SQL Server column whose type is one of the date/time types added in SQL Server 2008.
+Microsoft SQL Server includes a popular command-prompt utility named **bcp** for moving data from one table to another, whether on a single server or between servers. The class lets you write managed code solutions that provide similar functionality. There are other ways to load data into a SQL Server table (INSERT statements, for example), but offers a significant performance advantage over them. The class can be used to write data only to SQL Server tables. However, the data source is not limited to SQL Server; any data source can be used, as long as the data can be loaded to a instance or read with a instance. will fail when bulk loading a column of type into a SQL Server column whose type is one of the date/time types added in SQL Server 2008.
## Examples
-The following console application demonstrates how to load data using the class.
-In this example, a is used to copy data from the **Production.Product** table in the SQL Server **AdventureWorks** database to a similar table in the same database.
+The following console application demonstrates how to load data using the class.
+In this example, a is used to copy data from the **Production.Product** table in the SQL Server **AdventureWorks** database to a similar table in the same database.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -55,7 +55,7 @@ Note that the source data does not have to be located on SQL Server; you can use
.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -102,14 +102,14 @@ Transact-SQL `INSERT … SELECT` statement to copy the data.
## Remarks
If options include `UseInternalTransaction` and the `externalTransaction` argument is not null, an **InvalidArgumentException** is thrown.
-For examples demonstrating how to use `SqlBulkCopy` in a transaction, see [Transaction and Bulk Copy Operations](/dotnet/framework/data/adonet/sql/transaction-and-bulk-copy-operations).
+For examples demonstrating how to use `SqlBulkCopy` in a transaction, see [Transaction and Bulk Copy Operations](/sql/connect/ado-net/sql/transaction-bulk-copy-operations).
]]>
Performing Bulk Copy Operations
-
- ADO.NET Overview
+
+ Overview of the SqlClient driver
@@ -152,7 +152,7 @@ In this example, the source data is first read from a SQL Server table to a or loaded to a .
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -216,7 +216,7 @@ Then run the sample again without emptying the table. An exception is thrown and
added because of primary key constraint violations.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup). This code is provided to
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). This code is provided to
demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement
to copy the data.
@@ -252,10 +252,10 @@ operations on the same instance use
## Examples
The following console application demonstrates how to bulk load data in batches of 50 rows. For an example illustrating how
-works with a transaction, see [Transaction and Bulk Copy Operations](/dotnet/framework/data/adonet/sql/transaction-and-bulk-copy-operations).
+works with a transaction, see [Transaction and Bulk Copy Operations](/sql/connect/ado-net/sql/transaction-bulk-copy-operations).
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -284,7 +284,7 @@ In this example, the source data is first read from a SQL Server table to a or loaded to a .
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -307,7 +307,7 @@ Note that open instances are closed
The following example uses the same instance to add sales orders and their associated details to two destination tables. Because the **AdventureWorks** sales order tables are large, the sample reads only orders placed by a certain account number and bulk copies those orders and details to the destination tables. The method is used only after both bulk copy operations are complete.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup). This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
[!code-csharp[SqlBulkCopy.OrdersDetails#1](~/../sqlclient/doc/samples/SqlBulkCopy_OrdersDetails.cs#1)]
]]>
@@ -335,8 +335,12 @@ The following example uses the same is `true`, reads from an object using ,
-optimizing memory usage by using the streaming capabilities. When it's set to false, the class loads all the data returned by the
- object into memory before sending it to SQL Server or SQL Azure.
+optimizing memory usage by using the streaming capabilities. Streaming is only applicable to max data types (i.e.
+VARBINARY(MAX), VARCHAR(MAX), NVARCHAR(MAX), and XML). When is set to false,
+the class loads all the data returned by the object into memory before sending it to the server.
+
+> [!NOTE]
+> The main advantage of enabling streaming is reducing memory usage during bulk copy of max data types.
]]>
@@ -406,7 +410,7 @@ In this example, the connection is first used to read data from a SQL Server tab
be located on SQL Server; you can use any data source that can be read to an or loaded to a .
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
[!code-csharp[SqlBulkCopy.Single#1](~/../sqlclient/doc/samples/SqlBulkCopy_Single.cs#1)]
@@ -441,7 +445,7 @@ In this example, the connection is first used to read data from a SQL Server tab
Note that the source data does not have to be located on SQL Server; you can use any data source that can be read to an or loaded to a .
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup). This code is provided to
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). This code is provided to
demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT`
statement to copy the data.
@@ -466,7 +470,7 @@ Note that the settings of ) or SqlConnection.Close () from this event.
Doing this will cause an being thrown, and the object state will not change. If the user wants to cancel the
operation from the event, the property of the can be used.
-(See [Transaction and Bulk Copy Operations](/dotnet/framework/data/adonet/sql/transaction-and-bulk-copy-operations) for examples that use the
+(See [Transaction and Bulk Copy Operations](/sql/connect/ado-net/sql/transaction-bulk-copy-operations) for examples that use the
property.)
No action, such as transaction activity, is supported in the connection during the execution of the bulk copy operation, and it is recommended that you not use the same connection used
@@ -481,7 +485,7 @@ In this example, the connection is first used to read data from a SQL Server tab
SQL Server; you can use any data source that can be read to an or loaded to a .
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier
and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -504,7 +508,7 @@ and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
## Remarks
This value is incremented during the event and does not imply that this number of rows has been sent to the server or committed.
-During the execution of a bulk copy operation, this value can be accessed, but it cannot be changed. Any attempt to change it will throw an .
+This value can be accessed during or after the execution of a bulk copy operation.
]]>
@@ -588,7 +592,7 @@ The collection maps f
The following console application demonstrates how to bulk load data from a . The destination table is a table in the **AdventureWorks** database.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup). This code is provided
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). This code is provided
to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -632,7 +636,7 @@ The following Console application demonstrates how to bulk load data from a is created at run time and is the source of the `SqlBulkCopy` operation.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
[!code-csharp[SqlBulkCopy.DataTable#1](~/../sqlclient/doc/samples/SqlBulkCopy_DataTable.cs#1)]
@@ -646,8 +650,8 @@ This code is provided to demonstrate the syntax for using **SqlBulkCopy** only.
Performing Bulk Copy Operations
-
- ADO.NET Overview
+
+ Overview of the SqlClient driver
@@ -692,7 +696,7 @@ In this example, a is created at run time and three
The method is called with a `DataRowState.Unchanged` `rowState` argument, so only the two unchanged rows are bulk copied to the destination.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup). This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
[!code-csharp[SqlBulkCopy.DataRowState#1](~/../sqlclient/doc/samples/SqlBulkCopy_DataRowState.cs#1)]
]]>
@@ -720,7 +724,7 @@ The following console application demonstrates how to bulk load data from a is created at run time. A single row is selected from the to copy to the destination table.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup). This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
[!code-csharp[SqlBulkCopy.RowArray#1](~/../sqlclient/doc/samples/SqlBulkCopy_RowArray.cs#1)]
@@ -755,7 +759,7 @@ In this example, a is created at run time. A single
@@ -780,8 +784,6 @@ For more information about asynchronous programming in the .NET Framework Data P
Returned in the task object, the
object is closed before method execution.
-
- is specified in the connection string.
A
@@ -822,7 +824,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -850,9 +852,6 @@ For more information about asynchronous programming in the .NET Framework Data P
object is closed before method execution.
-
- is specified in the connection string.
-
A
did not specify a valid destination column name.
@@ -883,7 +882,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -921,8 +920,6 @@ For more information about asynchronous programming in the .NET Framework Data P
's associated connection was closed before the completed
returned.
-
- is specified in the connection string.
A
@@ -987,7 +984,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -1026,8 +1023,6 @@ For more information about asynchronous programming in the .NET Framework Data P
's associated connection was closed before the completed
returned.
-
- is specified in the connection string.
A
@@ -1068,7 +1063,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -1106,8 +1101,6 @@ For more information about asynchronous programming in the .NET Framework Data P
's associated connection was closed before the completed
returned.
-
- is specified in the connection string.
A
@@ -1140,7 +1133,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -1167,8 +1160,6 @@ For more information about asynchronous programming in the .NET Framework Data P
Returned in the task object, the
object is closed before method execution.
-
- is specified in the connection string.
A
@@ -1209,7 +1200,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -1236,8 +1227,6 @@ For more information about asynchronous programming in the .NET Framework Data P
Returned in the task object, the
object is closed before method execution.
-
- is specified in the connection string.
A
@@ -1271,7 +1260,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -1298,8 +1287,6 @@ For more information about asynchronous programming in the .NET Framework Data P
Returned in the task object, the
object is closed before method execution.
-
- is specified in the connection string.
A
@@ -1345,7 +1332,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -1372,8 +1359,6 @@ For more information about asynchronous programming in the .NET Framework Data P
Returned in the task object, the
object is closed before method execution.
-
- is specified in the connection string.
A
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMapping.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMapping.xml
index 51925e7dfa..f8d258ff32 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMapping.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMapping.xml
@@ -26,7 +26,7 @@ destination matches the number of columns in the source, and each destination co
objects are used to create a column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -54,7 +54,7 @@ Although the number of columns in the destination matches the number of columns
objects are used to create a column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -81,7 +81,7 @@ Although the number of columns in the destination matches the number of columns
objects are used to create a column map for the bulk copy based on the ordinal positions of the columns.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier
and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -108,7 +108,7 @@ the destination matches the number of columns in the source, the column names an
column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and
faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -135,7 +135,7 @@ the destination matches the number of columns in the source, the column names an
a column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup). This code is
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup). This code is
provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to
use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -162,7 +162,7 @@ destination matches the number of columns in the source, the column names and or
column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -192,7 +192,7 @@ Although the number of columns in the destination matches the number of columns
objects are used to create a column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -222,7 +222,7 @@ destination matches the number of columns in the source, the column names and or
column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -252,7 +252,7 @@ destination matches the number of columns in the source, the column names and or
column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -282,7 +282,7 @@ matches the number of columns in the source, the column names and ordinal positi
bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMappingCollection.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMappingCollection.xml
index 145e8407a0..5c8ddd2ef3 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMappingCollection.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnMappingCollection.xml
@@ -23,7 +23,7 @@ Although the number of columns in the destination matches the number of columns
object to create a column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to
use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -45,7 +45,7 @@ Although the number of columns in the destination matches the number of columns
objects are used to create a column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -73,7 +73,7 @@ Although the number of columns in the destination matches the number of columns
objects are used to create a column map for the bulk copy using the ordinal position of the source and destination columns.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -100,7 +100,7 @@ destination matches the number of columns in the source, the column names and or
column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -127,7 +127,7 @@ Although the number of columns in the destination matches the number of columns
objects are used to create a column map for the bulk copy.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -154,7 +154,7 @@ Although the number of columns in the destination matches the number of columns
object by specifying the column names.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -182,7 +182,7 @@ Although not strictly necessary in this example (because the ordinal positions o
The method must be used after the first bulk copy is performed and before the next bulk copy's column mappings are defined.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -249,7 +249,7 @@ Both bulk copies include a mapping for the **SalesOrderID**, so rather than clea
mapping and then adds the appropriate mappings for the second bulk copy operation.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -281,7 +281,7 @@ Both bulk copies include a mapping for the **SalesOrderID**, so rather than clea
**SalesOrderID** mapping and then adds the appropriate mappings for the second bulk copy operation.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHint.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHint.xml
index ff7a7130f4..d3e846546c 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHint.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHint.xml
@@ -31,7 +31,7 @@ The following example bulk copies data from a source table in the **AdventureWor
A SqlBulkCopyColumnOrderHint object is used to define the sort order for the ProductNumber destination column.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -58,7 +58,7 @@ The following example bulk copies data from a source table in the **AdventureWor
A SqlBulkCopyColumnOrderHint object is used to define the sort order for the ProductNumber destination column.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -88,7 +88,7 @@ The following example bulk copies data from a source table in the **AdventureWor
A SqlBulkCopyColumnOrderHint object is used to define the sort order for the ProductNumber destination column.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -118,7 +118,7 @@ The following example bulk copies data from a source table in the **AdventureWor
A SqlBulkCopyColumnOrderHint object is used to define the sort order for the ProductNumber destination column.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHintCollection.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHintCollection.xml
index 662ad0e652..1f6912efa5 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHintCollection.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyColumnOrderHintCollection.xml
@@ -29,7 +29,7 @@ The following example bulk copies data from a source table in the **AdventureWor
object to specify order hints for the bulk copy operation.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to
use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -51,7 +51,7 @@ The following example bulk copies data from a source table in the **AdventureWor
A SqlBulkCopyColumnOrderHint object is used to define the sort order for the **ProductNumber** destination column.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -78,7 +78,7 @@ The following example bulk copies data from a source table in the **AdventureWor
A SqlBulkCopyColumnOrderHint object is added to the by providing the destination column name and its sort order.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -107,7 +107,7 @@ The example defines a column order hint for each bulk copy operation.
The method must be used after the first bulk copy is performed and before the next bulk copy's order hint is defined.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -176,7 +176,7 @@ The following example performs two bulk copy operations. The first operation cop
The example defines a column order hint for the **OrderDate** column in the first bulk copy operation. The hint is removed before the second bulk copy operation.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
@@ -208,7 +208,7 @@ The following example performs two bulk copy operations. The first operation cop
The example defines a column order hint for the **OrderDate** column in the first bulk copy operation. The hint is removed before the second bulk copy operation.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance, it is easier and faster to use a
Transact-SQL `INSERT … SELECT` statement to copy the data.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyOptions.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyOptions.xml
index f1433ee4ff..152fcbde42 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyOptions.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlBulkCopyOptions.xml
@@ -18,7 +18,7 @@ Next, run the sample again without emptying the table. An exception is thrown, a
primary key violations.
> [!IMPORTANT]
-> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/dotnet/framework/data/adonet/sql/bulk-copy-example-setup).
+> This sample will not run unless you have created the work tables as described in [Bulk Copy Example Setup](/sql/connect/ado-net/sql/bulk-copy-example-setup).
This code is provided to demonstrate the syntax for using **SqlBulkCopy** only. If the source and destination tables are in the same SQL Server instance,
it is easier and faster to use a Transact-SQL `INSERT … SELECT` statement to copy the data.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml
index e013016ee9..01d30ee8d3 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlClientMetaDataCollectionNames.xml
@@ -60,5 +60,9 @@
A constant for use with the **GetSchema** method that represents the **ColumnSetColumns** collection.To be added.
+
+ A constant for use with the **GetSchema** method that represents the **StructuredTypeMembers** collection.
+ To be added.
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCertificateStoreProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCertificateStoreProvider.xml
index 6c70855915..697e9b8539 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCertificateStoreProvider.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCertificateStoreProvider.xml
@@ -26,7 +26,7 @@
The master key path.
The encryption algorithm. Currently, the only valid value is: RSA_OAEP
- The encrypted column encryption key.
+ The plaintext column encryption key.
Encrypts a column encryption key using the certificate with the specified key path and using the specified algorithm. The format of the key path should be
"Local Machine/My/<certificate_thumbprint>" or "Current User/My/<certificate_thumbprint>".
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCngProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCngProvider.xml
index 3c2f528166..30d0640781 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCngProvider.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCngProvider.xml
@@ -30,7 +30,7 @@
The master key path.
The encryption algorithm.
- The encrypted column encryption key.
+ The plaintext column encryption key.
Encrypts the given plain text column encryption key using an asymmetric key specified by the key path and the specified algorithm. The key path will be in the format of [ProviderName]/KeyIdentifier and should be an asymmetric key stored in the specified CNG key store provider. The valid algorithm used to encrypt/decrypt the CEK is 'RSA_OAEP'.The encrypted column encryption key.To be added.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCspProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCspProvider.xml
index 26b62bb5f8..9e360781be 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCspProvider.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCspProvider.xml
@@ -28,7 +28,7 @@ Enables storing Always Encrypted column master key keys in a store, such as a ha
The master key path.
The encryption algorithm.
- The encrypted column encryption key.
+ The plaintext column encryption key.
Encrypts the given plain text column encryption key using an asymmetric key specified by the key path and the specified algorithm. The key path will be in the format of [ProviderName]/KeyIdentifier and should be an asymmetric key stored in the specified CSP provider. The valid algorithm used to encrypt/decrypt the CEK is 'RSA_OAEP'.The encrypted column encryption key.To be added.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionKeyStoreProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionKeyStoreProvider.xml
index 02cadd325f..7c2dc715fd 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionKeyStoreProvider.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionKeyStoreProvider.xml
@@ -1,9 +1,12 @@
- Base class for all key store providers. A custom provider must derive from this class and override its member functions and then register it using SqlConnection.RegisterColumnEncryptionKeyStoreProviders(). For details see, Always Encrypted.
+ Base class for all key store providers. A custom provider must derive from this class and override its member functions and then register it using
+ ,
+ or
+ .
+ For details see, Always Encrypted.
- To be added.Initializes a new instance of the SqlColumnEncryptionKeyStoreProviderClass.
@@ -21,7 +24,7 @@
The master key path.
The encryption algorithm.
- The encrypted column encryption key.
+ The plaintext column encryption key.
Encrypts a column encryption key using the column master key with the specified key path and using the specified algorithm.Returns . The encrypted column encryption key.To be added.
@@ -55,5 +58,17 @@ The When implemented in a derived class, the method is expected to return true if the specified signature is valid, or false if the specified signature is not valid. The default implementation throws NotImplementedException.
To be added.
+
+ Gets or sets the lifespan of the decrypted column encryption key in the cache. Once the timespan has elapsed, the decrypted column encryption key is discarded and must be revalidated.
+
+ . Any caching implementation should reference the value of this property before caching a column encryption key and not cache it if the value is zero. This will avoid duplicate caching and possible user confusion when they are trying to configure key caching.
+ ]]>
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml
index 4dbe1f6511..6aac0a9d42 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml
@@ -254,7 +254,7 @@ The following console application creates updates data within the **AdventureWor
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -281,19 +281,18 @@ The following console application creates updates data within the **AdventureWor
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
+
An error occurred in a
@@ -301,7 +300,7 @@ The following console application creates updates data within the **AdventureWor
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -310,7 +309,7 @@ The following console application creates updates data within the **AdventureWor
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -373,7 +372,7 @@ To set up this example, create a new Windows application. Put a
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -400,19 +399,18 @@ To set up this example, create a new Windows application. Put a
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
+
@@ -457,7 +455,7 @@ The following console application starts the process of retrieving a data reader
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -484,19 +482,18 @@ The following console application starts the process of retrieving a data reader
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
+
An error occurred in a
@@ -504,7 +501,7 @@ The following console application starts the process of retrieving a data reader
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -513,7 +510,7 @@ The following console application starts the process of retrieving a data reader
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -570,7 +567,7 @@ This example also passes the `CommandBehavior.CloseConnection` and `CommandBehav
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -597,19 +594,18 @@ This example also passes the `CommandBehavior.CloseConnection` and `CommandBehav
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
+
An error occurred in a
@@ -617,7 +613,7 @@ This example also passes the `CommandBehavior.CloseConnection` and `CommandBehav
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -626,7 +622,7 @@ This example also passes the `CommandBehavior.CloseConnection` and `CommandBehav
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -694,7 +690,7 @@ To set up this example, create a new Windows application. Put a
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -721,19 +717,18 @@ To set up this example, create a new Windows application. Put a
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
+
An error occurred in a
@@ -741,7 +736,7 @@ To set up this example, create a new Windows application. Put a
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -750,7 +745,7 @@ To set up this example, create a new Windows application. Put a
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -829,7 +824,7 @@ This example passes the `CommandBehavior.CloseConnection` value in the `behavior
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -856,19 +851,18 @@ This example passes the `CommandBehavior.CloseConnection` value in the `behavior
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
+
An error occurred in a
@@ -876,7 +870,7 @@ This example passes the `CommandBehavior.CloseConnection` value in the `behavior
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -885,7 +879,7 @@ This example passes the `CommandBehavior.CloseConnection` value in the `behavior
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -943,7 +937,7 @@ The following console application starts the process of retrieving XML data asyn
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -970,18 +964,17 @@ The following console application starts the process of retrieving XML data asyn
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
An error occurred in a
@@ -990,7 +983,7 @@ The following console application starts the process of retrieving XML data asyn
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -999,7 +992,7 @@ The following console application starts the process of retrieving XML data asyn
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -1077,7 +1070,7 @@ To set up this example, create a new Windows application. Put a
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -1104,19 +1097,18 @@ To set up this example, create a new Windows application. Put a
- The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this
-
- .
-
- -or-
-
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
+
+ - or -
+
+
+ is set to true and a parameter with direction Output or InputOutput has been added to the collection.
+
An error occurred in a
@@ -1124,7 +1116,7 @@ To set up this example, create a new Windows application. Put a
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -1133,7 +1125,7 @@ To set up this example, create a new Windows application. Put a
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -1177,14 +1169,11 @@ The following example demonstrates the use of the
- Gets or sets the column encryption setting for this command.
+ Gets the column encryption setting for this command.
The column encryption setting for this command.
-
- To be added.
-
@@ -1205,7 +1194,7 @@ The Microsoft .NET Framework Data Provider for SQL Server does not support the q
SELECT * FROM dbo.Customers WHERE CustomerID = @CustomerID
```
-For more information, see [Configuring Parameters and Parameter Data Types](/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types).
+For more information, see [Configuring parameters](/sql/connect/ado-net/configure-parameters).
## Examples
The following example creates a and sets some of its properties.
@@ -1230,8 +1219,6 @@ A value of 0 indicates no limit (an attempt to execute a command will wait indef
> [!NOTE]
> The property will be ignored during old-style asynchronous method calls such as . It will be honored by the newer async methods such as .
- has no effect when the command is executed against a context connection (a opened with "context connection=true" in the connection string).
-
> [!NOTE]
> This property is the cumulative time-out (for all network packets that are read during the invocation of a method) for all network reads during command execution or processing of the results. A time-out can still occur after the first row is returned, and does not include user processing time, only network read time.
@@ -1265,7 +1252,7 @@ The Microsoft .NET Framework Data Provider for SQL Server does not support the q
SELECT * FROM Customers WHERE CustomerID = @CustomerID
-For more information, see [Configuring Parameters and Parameter Data Types](/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types).
+For more information, see [Configuring parameters](/sql/connect/ado-net/configure-parameters).
## Examples
The following example creates a and sets some of its properties.
@@ -1396,6 +1383,33 @@ The method is a st
To be added.
+
+
+ Gets or sets a value indicating whether the command object should optimize parameter performance by disabling Output and InputOutput directions when submitting the command to the SQL Server.
+
+
+ A value indicating whether the command object should optimize parameter performance by disabling Output and InputOuput parameter directions when submitting the command to the SQL Server.
+ The default is .
+
+
+
+ [!NOTE]
+If the option is enabled and a parameter with Direction Output or InputOutput is present in the Parameters collection an InvalidOperationException will be thrown when the command is executed.
+
+]]>
+
+
+
The
@@ -1614,7 +1628,7 @@ The following example creates a and t
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -1641,7 +1655,7 @@ The following example creates a and t
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -1650,12 +1664,12 @@ The following example creates a and t
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -1664,7 +1678,7 @@ The following example creates a and t
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -1683,7 +1697,7 @@ The following example creates a and t
@@ -1693,7 +1707,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -1724,18 +1738,14 @@ For more information about asynchronous programming in the .NET Framework Data P
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -1744,7 +1754,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -1753,7 +1763,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -1798,7 +1808,7 @@ The following example creates a , and
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -1825,7 +1835,7 @@ The following example creates a , and
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The current state of the connection is closed.
@@ -1838,7 +1848,7 @@ The following example creates a , and
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -1847,7 +1857,7 @@ The following example creates a , and
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -1856,7 +1866,7 @@ The following example creates a , and
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -1907,7 +1917,7 @@ The following example creates a , and
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -1930,7 +1940,7 @@ The following example creates a , and
.
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -1939,12 +1949,12 @@ The following example creates a , and
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -1953,7 +1963,7 @@ The following example creates a , and
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -1975,7 +1985,7 @@ The following example creates a , and
@@ -1985,7 +1995,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2021,18 +2031,14 @@ For more information about asynchronous programming in the .NET Framework Data P
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2041,7 +2047,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2050,7 +2056,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2079,7 +2085,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -2089,7 +2095,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2123,18 +2129,14 @@ For more information about asynchronous programming in the .NET Framework Data P
-or-
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2143,7 +2145,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2152,7 +2154,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2179,7 +2181,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -2190,7 +2192,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2226,18 +2228,14 @@ For more information about asynchronous programming in the .NET Framework Data P
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2246,7 +2244,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2255,7 +2253,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2287,7 +2285,7 @@ For more information about asynchronous programming in the .NET Framework Data P
@@ -2297,7 +2295,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2333,18 +2331,14 @@ For more information about asynchronous programming in the .NET Framework Data P
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2353,7 +2347,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2362,7 +2356,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2400,7 +2394,7 @@ The following example creates a and t
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2427,12 +2421,12 @@ The following example creates a and t
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2441,7 +2435,7 @@ The following example creates a and t
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2450,7 +2444,7 @@ The following example creates a and t
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2471,7 +2465,7 @@ The following example creates a and t
@@ -2481,7 +2475,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2512,18 +2506,14 @@ For more information about asynchronous programming in the .NET Framework Data P
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2532,7 +2522,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2541,7 +2531,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2591,7 +2581,7 @@ The following example creates a and t
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2618,12 +2608,12 @@ The following example creates a and t
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2632,7 +2622,7 @@ The following example creates a and t
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2641,7 +2631,7 @@ The following example creates a and t
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2666,7 +2656,7 @@ The following example creates a and t
## Remarks
The **XmlReader** returned by this method does not support asynchronous operations.
-For more information about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/dotnet/framework/data/adonet/asynchronous-programming).
+For more information about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/sql/connect/ado-net/asynchronous-programming).
]]>
@@ -2676,7 +2666,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2707,18 +2697,14 @@ For more information about asynchronous programming in the .NET Framework Data P
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2727,7 +2713,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2736,7 +2722,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2764,7 +2750,7 @@ For more information about asynchronous programming in the .NET Framework Data P
## Remarks
The **XmlReader** returned by this method does not support asynchronous operations.
-For more information about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/dotnet/framework/data/adonet/asynchronous-programming).
+For more information about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/sql/connect/ado-net/asynchronous-programming).
]]>
@@ -2774,7 +2760,7 @@ For more information about asynchronous programming in the .NET Framework Data P
was set to
- . For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ . For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
-or-
@@ -2805,18 +2791,14 @@ For more information about asynchronous programming in the .NET Framework Data P
The
- closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
-
- -or-
-
- is specified in the connection string.
+ closed or dropped during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
SQL Server returned an error while executing the command text.
-or-
- A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ A timeout occurred during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
An error occurred in a
@@ -2825,7 +2807,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
The
@@ -2834,7 +2816,7 @@ For more information about asynchronous programming in the .NET Framework Data P
or
- object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ object was closed during a streaming operation. For more information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -2854,6 +2836,105 @@ You must set the value for this property before the command is executed for it t
]]>
+
+ Dictionary of custom column encryption key providers
+ Registers the encryption key store providers on the instance. If this function has been called, any providers registered using the or
+ methods will be ignored. This function can be called more than once. This does shallow copying of the dictionary so that the app cannot alter the custom provider list once it has been set.
+
+ A null dictionary was provided.
+
+ -or-
+
+ A string key in the dictionary was null or empty.
+
+ -or-
+
+ A value in the dictionary was null.
+
+
+ A string key in the dictionary started with "MSSQL_". This prefix is reserved for system providers.
+
+
+
+
+
+
+
+ Gets or sets a value that specifies the
+
+ object bound to this command.
+
+
+ When set to null (default), the default non-retriable provider will be used.
+
+
+ type.
+2. Create a by using one of the following static methods of the class:
+ -
+ -
+ -
+ -
+3. Assign the object to the `RetryLogicProvider` property.
+
+> [!NOTE]
+> Detecting retriable exceptions is a vital part of the retry pattern. Before applying retry logic, it is important to investigate exceptions and choose a retry provider that best fits your scenario. First, log your exceptions and find transient faults.
+
+> [!NOTE]
+> The command **timeout** restarts for each execution of a command within the retry logic and after applying the retry time delay. There is no timing overlap between these two actions.
+
+> [!NOTE]
+> The default retry logic provider is not enabled unless it is configured in an application configuration file. For more information, see [Configurable retry logic configuration file](/sql/connect/ado-net/configurable-retry-logic-config-file-sqlclient).
+
+> [!CAUTION]
+> A command with isn't compatible with the built-in retry logic. The underlying connection is immediately closed after the first execution attempt and is no longer available for subsequent retries.
+
+## Example
+The following sample creates a database and establishes an active connection to it. While the database has an active connection, it tries to drop it with a new and a that uses a . You should kill the active connection through the database to unblock the second command before exceeding the number of retries.
+The blocking connection simulates a situation like a command still running in the database and unlikely to finish.
+
+[!code-csharp[SqlConfigurableRetryLogic_SqlCommand#1](~/../sqlclient/doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs#1)]
+
+### How to use with synchronous commands
+
+[!code-csharp[SqlConfigurableRetryLogic_SqlCommand#2](~/../sqlclient/doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs#2)]
+
+### How to use with asynchoronous commands
+
+[!code-csharp[SqlConfigurableRetryLogic_SqlCommand#3](~/../sqlclient/doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs#3)]
+
+### How to use with legacy asynchronous commands
+Besides assigning the provider to the command and executing the command, it's possible to run it directly using the following methods:
+-
+-
+-
+
+[!code-csharp[SqlConfigurableRetryLogic_SqlCommand#4](~/../sqlclient/doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs#4)]
+
+> [!NOTE]
+> The Asynchronous Programming Model (APM) is a legacy pattern that uses a pair of methods starting with `Begin` and `End`, and an interface called `IAsyncResult`. It's not recommended to use this pattern in new applications. These methods are for backwards compatibility.
+
+]]>
+
+
Gets or sets a value indicating whether the application should automatically receive query notifications from a common
@@ -2898,7 +2979,7 @@ SELECT * FROM Customers WHERE CustomerID = @CustomerID
> [!NOTE]
> If the parameters in the collection do not match the requirements of the query to be executed, an error may result.
-For more information, see [Configuring Parameters and Parameter Data Types](/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types).
+For more information, see [Configuring parameters](/sql/connect/ado-net/configure-parameters).
## Examples
The following example demonstrates how to create a and add parameters to the .
@@ -3001,7 +3082,7 @@ You cannot set the pro
## Remarks
The default value is **Both** unless the command is automatically generated (as in the case of the ), in which case the default is **None**.
-For more information about using the **UpdatedRowSource** property, see [DataAdapter Parameters](/dotnet/framework/data/adonet/dataadapter-parameters).
+For more information about using the **UpdatedRowSource** property, see [DataAdapter Parameters](/sql/connect/ado-net/dataadapter-parameters).
]]>
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlCommandBuilder.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlCommandBuilder.xml
index e242e17c2c..87ddd2c8b8 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlCommandBuilder.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlCommandBuilder.xml
@@ -142,7 +142,7 @@ When you create a new instance of with arbitrary Transact-SQL statements, such as a parameterized SELECT statement.
-For more information, see [Configuring Parameters and Parameter Data Types](/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types).
+For more information, see [Configuring parameters](/sql/connect/ado-net/configure-parameters).
]]>
@@ -165,7 +165,7 @@ You can also use if it changes the statement in any way. Otherwise, the will still be using information from the previous statement, which might not be correct. The SQL statements are first generated when the application calls either or .
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -183,7 +183,7 @@ You can also use if it changes the statement in any way. Otherwise, the will still be using information from the previous statement, which might not be correct. The SQL statements are first generated when the application calls either or .
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -210,7 +210,7 @@ The default behavior, when generating parameter names, is to use `@p1`, `@p2`, a
- A returned from the **GetSchema** method call and found in the collection is specified.
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -227,7 +227,7 @@ You can also use if it changes the statement in any way. Otherwise, the will still be using information from the previous statement, which might not be correct. The Transact-SQL statements are first generated when the application calls either or .
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -245,7 +245,7 @@ You can also use if it changes the statement in any way. Otherwise, the will still be using information from the previous statement, which might not be correct. The Transact-SQL statements are first generated when the application calls either or .
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -272,7 +272,7 @@ The default behavior, when generating parameter names, is to use `@p1`, `@p2`, a
- A returned from the **GetSchema** method call and found in the collection is specified.
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -313,7 +313,7 @@ You can also use if it changes the statement in any way. Otherwise, the will still be using information from the previous statement, which might not be correct. The Transact-SQL statements are first generated when the application calls either or .
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -331,7 +331,7 @@ You can also use if it changes the statement in any way. Otherwise, the will still be using information from the previous statement, which might not be correct. The Transact-SQL statements are first generated when the application calls either or .
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -358,7 +358,7 @@ The default behavior, when generating parameter names, is to use `@p1`, `@p2`, a
- A returned from the **GetSchema** method call and found in the collection is specified.
-For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
]]>
@@ -431,9 +431,9 @@ Generally, database servers indicate the schema for a identifier by separating t
Given a quoted identifier, returns the correct unquoted form of that identifier. This includes correctly unescaping any embedded quotes in the identifier.The unquoted identifier, with embedded quotes properly unescaped.To be added.
- Connecting and Retrieving Data in ADO.NET
- Using the .NET Framework Data Provider for SQL Server
- ADO.NET Overview
+ Connecting and Retrieving Data in ADO.NET
+ Using the .NET Framework Data Provider for SQL Server
+ Overview of the SqlClient driver
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConfigurableRetryFactory.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConfigurableRetryFactory.xml
new file mode 100644
index 0000000000..cbeb9de0b1
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConfigurableRetryFactory.xml
@@ -0,0 +1,116 @@
+
+
+
+
+ Provides different retry logic providers with a common list of transient errors.
+
+
+
+
+
+
+ An object of containing the configuration for the object.
+ Provides an exponential time interval retry logic provider.
+ A object.
+
+ [!NOTE]
+> The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time.
+
+]]>
+
+ If the `retryLogicOption` parameter was null.
+ If at least one of the following conditions occurs:
+- `NumberOfTries` is less than 1 or bigger than 60.
+- `DeltaTime` is bigger than 120 seconds.
+- `MinTimeInterval` is bigger than 120 seconds.
+- `MaxTimeInterval` is bigger than 120 seconds.
+- `MinTimeInterval` is not less than `MaxTimeInterval`.
+
+
+
+ An object of containing the configuration for the object.
+ Provides an incremental time interval retry logic provider.
+ A object.
+
+ [!NOTE]
+> The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time.
+
+]]>
+
+ If the `retryLogicOption` parameter was null.
+ If at least one of the following conditions occurs:
+- `NumberOfTries` is less than 1 or bigger than 60.
+- `DeltaTime` is bigger than 120 seconds.
+- `MinTimeInterval` is bigger than 120 seconds.
+- `MaxTimeInterval` is bigger than 120 seconds.
+- `MinTimeInterval` is not less than `MaxTimeInterval`.
+
+
+
+ An object of containing the configuration for the object.
+ Provides a fixed interval time retry logic provider.
+ A object.
+
+ [!NOTE]
+> The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time.
+
+]]>
+
+ If the `retryLogicOption` parameter was null.
+ If at least one of the following conditions occurs:
+- `NumberOfTries` is less than 1 or bigger than 60.
+- `DeltaTime` is bigger than 120 seconds.
+- `MinTimeInterval` is bigger than 120 seconds.
+- `MaxTimeInterval` is bigger than 120 seconds.
+- `MinTimeInterval` is not less than `MaxTimeInterval`.
+
+
+
+ Provides a non-retriable provider with a that returns .
+ A object.
+
+ [!NOTE]
+> The returned provider of this function performs a single execution without any retry logic.
+
+]]>
+
+
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml
index 24aac534e4..bfc53dddac 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml
@@ -16,7 +16,7 @@
If the goes out of scope, it won't be closed. Therefore, you must explicitly close the connection by calling `Close` or `Dispose`. `Close` and `Dispose` are functionally equivalent. If the connection pooling value `Pooling` is set to `true` or `yes`, the underlying connection is returned back to the connection pool. On the other hand, if `Pooling` is set to `false` or `no`, the underlying connection to the server is actually closed.
> [!NOTE]
-> Login and logout events will not be raised on the server when a connection is fetched from or returned to the connection pool, because the connection is not actually closed when it is returned to the connection pool. For more information, see [SQL Server Connection Pooling (ADO.NET)](/dotnet/framework/data/adonet/sql-server-connection-pooling).
+> Login and logout events will not be raised on the server when a connection is fetched from or returned to the connection pool, because the connection is not actually closed when it is returned to the connection pool. For more information, see [SQL Server Connection Pooling (ADO.NET)](/sql/connect/ado-net/sql-server-connection-pooling).
To ensure that connections are always closed, open the connection inside of a `using` block, as shown in the following code fragment. Doing so ensures that the connection is automatically closed when the code exits the block.
@@ -37,13 +37,13 @@ using (SqlConnection connection = new SqlConnection(connectionString))
```
> [!NOTE]
-> To deploy high-performance applications, you must use connection pooling. When you use the .NET Framework Data Provider for SQL Server, you do not have to enable connection pooling because the provider manages this automatically, although you can modify some settings. For more information, see [SQL Server Connection Pooling (ADO.NET)](/dotnet/framework/data/adonet/sql-server-connection-pooling).
+> To deploy high-performance applications, you must use connection pooling. When you use the .NET Framework Data Provider for SQL Server, you do not have to enable connection pooling because the provider manages this automatically, although you can modify some settings. For more information, see [SQL Server Connection Pooling (ADO.NET)](/sql/connect/ado-net/sql-server-connection-pooling).
If a is generated by the method executing a , the remains open when the severity level is 19 or less. When the severity level is 20 or greater, the server ordinarily closes the . However, the user can reopen the connection and continue.
An application that creates an instance of the object can require all direct and indirect callers to have sufficient permission to the code by setting declarative or imperative security demands. makes security demands using the object. Users can verify that their code has sufficient permissions by using the object. Users and administrators can also use the [Caspol.exe (Code Access Security Policy Tool)](/dotnet/framework/tools/caspol-exe-code-access-security-policy-tool) to modify security policy at the machine, user, and enterprise levels. For more information, see [Security in .NET](/dotnet/standard/security/). For an example demonstrating how to use security demands, see [Code Access Security and ADO.NET](/dotnet/framework/data/adonet/code-access-security).
- For more information about handling warning and informational messages from the server, see [Connection Events](/dotnet/framework/data/adonet/connection-events). For more information about SQL Server engine errors and error messages, see [Database Engine Events and Errors](/sql/relational-databases/errors-events/database-engine-events-and-errors).
+ For more information about handling warning and informational messages from the server, see [Connection Events](/sql/connect/ado-net/connection-events). For more information about SQL Server engine errors and error messages, see [Database Engine Events and Errors](/sql/relational-databases/errors-events/database-engine-events-and-errors).
> [!CAUTION]
> You can force TCP instead of shared memory. You can do that by prefixing tcp: to the server name in the connection string or you can use localhost.
@@ -362,9 +362,6 @@ End Module
The connection string contains any combination of , , or .
--or-
-
-The connection string contains .
-or-
@@ -432,7 +429,7 @@ The connection string contains .
If the goes out of scope, it won't be closed. Therefore, you must explicitly close the connection by calling `Close` or `Dispose`. `Close` and `Dispose` are functionally equivalent. If the connection pooling value `Pooling` is set to `true` or `yes`, the underlying connection is returned back to the connection pool. On the other hand, if `Pooling` is set to `false` or `no`, the underlying connection to the server is closed.
> [!NOTE]
-> Login and logout events will not be raised on the server when a connection is fetched from or returned to the connection pool, because the connection is not actually closed when it is returned to the connection pool. For more information, see [SQL Server Connection Pooling (ADO.NET)](/dotnet/framework/data/adonet/sql-server-connection-pooling).
+> Login and logout events will not be raised on the server when a connection is fetched from or returned to the connection pool, because the connection is not actually closed when it is returned to the connection pool. For more information, see [SQL Server Connection Pooling (ADO.NET)](/sql/connect/ado-net/sql-server-connection-pooling).
> [!CAUTION]
> Do not call `Close` or `Dispose` on a Connection, a DataReader, or any other managed object in the `Finalize` method of your class. In a finalizer, you should only release unmanaged resources that your class owns directly. If your class does not own any unmanaged resources, do not include a `Finalize` method in your class definition. For more information, see [Garbage Collection](/dotnet/standard/garbage-collection/).
@@ -472,23 +469,23 @@ The connection string contains .
The list of trusted master key paths for the column encryption.To be added.
-
-
- Gets the default wait time (in seconds) before terminating the attempt to execute a command and generating an error. The default is 30 seconds.
-
-
- The time in seconds to wait for the command to execute. The default is 30 seconds.
-
-
-
+
+ Gets the default wait time (in seconds) before terminating the attempt to execute a command and generating an error. The default is 30 seconds.
+
+
+ The time in seconds to wait for the command to execute. The default is 30 seconds.
+
+
+
-
-
+
+
Gets or sets the string used to open a SQL Server database.The connection string that includes the source database name, and other parameters needed to establish the initial connection. The default value is an empty string.
@@ -504,7 +501,7 @@ The connection string contains .
"Persist Security Info=False;Integrated Security=true;Initial Catalog=Northwind;server=(local)"
```
- Use the new to construct valid connection strings at run time. For more information, see [Connection String Builders](/dotnet/framework/data/adonet/connection-string-builders).
+ Use the new to construct valid connection strings at run time. For more information, see [Connection String Builders](/sql/connect/ado-net/connection-string-builders).
The property can be set only when the connection is closed. Many of the connection string values have corresponding read-only properties. When the connection string is set, these properties are updated, except when an error is detected. In this case, none of the properties are updated. properties return only those settings that are contained in the .
@@ -527,47 +524,50 @@ The connection string contains .
|Addr|N/A|Synonym of **Data Source**.|
|Address|N/A|Synonym of **Data Source**.|
|App|N/A|Synonym of **Application Name**.|
-|Application Name|N/A|The name of the application, or '.NET SQLClient Data Provider' if no application name is provided.
An application name can be 128 characters or less.|
-|Application Intent
-or-
ApplicationIntent|ReadWrite|Declares the application workload type when connecting to a server. Possible values are `ReadOnly` and `ReadWrite`. For example:
`ApplicationIntent=ReadOnly`
For more information about SqlClient support for Always On Availability Groups, see [SqlClient Support for High Availability, Disaster Recovery](/dotnet/framework/data/adonet/sql/sqlclient-support-for-high-availability-disaster-recovery).|
-|Asynchronous Processing
-or-
Async|'false'|When `true`, enables asynchronous operation support. Recognized values are `true`, `false`, `yes`, and `no`.
This property is ignored beginning in .NET Framework 4.5. For more information about SqlClient support for asynchronous programming, see [Asynchronous Programming](/dotnet/framework/data/adonet/asynchronous-programming).|
-|Attestation Protocol|N/A|Gets or sets the value of Attestation Protocol.
ApplicationIntent|ReadWrite|Declares the application workload type when connecting to a server. Possible values are `ReadOnly` and `ReadWrite`. For example:
`ApplicationIntent=ReadOnly`
For more information about SqlClient support for Always On Availability Groups, see [SqlClient Support for High Availability, Disaster Recovery](/sql/connect/ado-net/sql/sqlclient-support-high-availability-disaster-recovery).|
+|Application Name|N/A|The name of the application. If no application name is provided, 'Framework Microsoft SqlClient Data Provider' when running on .NET Framework and 'Core Microsoft SqlClient Data Provider' otherwise.
An application name can be 128 characters or less.|
|AttachDBFilename
-or-
Extended Properties
-or-
Initial File Name|N/A|The name of the primary database file, including the full path name of an attachable database. AttachDBFilename is only supported for primary data files with an .mdf extension.
If the value of the AttachDBFileName key is specified in the connection string, the database is attached and becomes the default database for the connection.
If this key is not specified and if the database was previously attached, the database will not be reattached. The previously attached database will be used as the default database for the connection.
If this key is specified together with the AttachDBFileName key, the value of this key will be used as the alias. However, if the name is already used in another attached database, the connection will fail.
The path may be absolute or relative by using the DataDirectory substitution string. If DataDirectory is used, the database file must exist within a subdirectory of the directory pointed to by the substitution string. **Note:** Remote server, HTTP, and UNC path names are not supported.
The database name must be specified with the keyword 'database' (or one of its aliases) as in the following:
An error will be generated if a log file exists in the same directory as the data file and the 'database' keyword is used when attaching the primary data file. In this case, remove the log file. Once the database is attached, a new log file will be automatically generated based on the physical path.|
-|Authentication|N/A|The authentication method used for [Connecting to SQL Database By Using Azure Active Directory Authentication](https://azure.microsoft.com/documentation/articles/sql-database-aad-authentication/#7-connect-to-your-database-by-using-azure-active-directory-identities).
Valid values are:
`Active Directory Integrated`, `Active Directory Interactive`, `Active Directory Password`, `Sql Password`. Currently `Active Directory Integrated` and `Active Directory Interactive` modes of authentication are supported only for .NET Framework. |
-|Column Encryption Setting|N/A|Enables or disables [Always Encrypted](/sql/relational-databases/security/encryption/always-encrypted-database-engine?view=sql-server-2017) functionality for the connection.|
+|Attestation Protocol|NotSpecified|Gets or sets the value of Attestation Protocol.
When no value is specified, secure enclaves are disabled on the connection.
Valid values are: `AAS` `HGS` `None` (Only valid in v3.1 and v4.1+))|
+|Authentication|N/A|The authentication method used for [Connecting to SQL Database By Using Azure Active Directory Authentication](https://azure.microsoft.com/documentation/articles/sql-database-aad-authentication/#7-connect-to-your-database-by-using-azure-active-directory-identities).
For additional information see [Using Azure Active Directory authentication with SqlClient](https://docs.microsoft.com/sql/connect/ado-net/sql/azure-active-directory-authentication?view=sql-server-ver15).|
+|Column Encryption Setting|disabled|Enables or disables [Always Encrypted](/sql/relational-databases/security/encryption/always-encrypted-database-engine) functionality for the connection. Supported values are: `enabled` and `disabled`|
|Command Timeout|30|The default wait time (in seconds) before terminating the attempt to execute a command and generating an error.
Valid values are greater than or equal to 0 and less than or equal to 2147483647.|
+|Connect Retry Count
-or-
ConnectRetryCount|1|Controls the number of reconnection attempts after the client identifies an idle connection failure. Valid values are 0 to 255. The default is 1. 0 means do not attempt to reconnect (disable connection resiliency).
For additional information about idle connection resiliency, see[.NET SqlConnection parameters for connection retry](https://learn.microsoft.com/azure/azure-sql/database/troubleshoot-common-connectivity-issues?view=azuresql#net-sqlconnection-parameters-for-connection-retry) and [Technical Article - Idle Connection Resiliency](https://go.microsoft.com/fwlink/?LinkId=393996).|
+|Connect Retry Interval
-or-
ConnectRetryInterval|10|Specifies the time between each connection retry attempt (`ConnectRetryCount`). Valid values are 1 to 60 seconds (default=10), applied after the first reconnection attempt. When a broken connection is detected, the client immediately attempts to reconnect; this is the first reconnection attempt and only occurs if `ConnectRetryCount` is greater than 0. If the first reconnection attempt fails and `ConnectRetryCount` is greater than 1, the client waits `ConnectRetryInterval` to try the second and subsequent reconnection attempts.
For additional information about idle connection resiliency, see[.NET SqlConnection parameters for connection retry](https://learn.microsoft.com/azure/azure-sql/database/troubleshoot-common-connectivity-issues?view=azuresql#net-sqlconnection-parameters-for-connection-retry) and [Technical Article - Idle Connection Resiliency](https://go.microsoft.com/fwlink/?LinkId=393996).|
|Connect Timeout
-or-
Connection Timeout
-or-
Timeout|15|The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error.
Valid values are greater than or equal to 0 and less than or equal to 2147483647.
When opening a connection to a Azure SQL Database, set the connection timeout to 30 seconds.|
-|Connection Lifetime
-or-
Load Balance Timeout|0|When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified by `Connection Lifetime`. This is useful in clustered configurations to force load balancing between a running server and a server just brought online.
A value of zero (0) causes pooled connections to have the maximum connection timeout.|
-|Connect Retry Count
-or-
ConnectRetryCount|1|Controls the number of reconnection attempts after the client identifies an idle connection failure. Valid values are 0 to 255. The default is 1. 0 means do not attempt to reconnect (disable connection resiliency).
For additional information about idle connection resiliency, see [Technical Article - Idle Connection Resiliency](https://go.microsoft.com/fwlink/?LinkId=393996).|
-|Connect Retry Interval
-or-
ConnectRetryInterval|10|Specifies the time between each connection retry attempt (ConnectRetryCount). Valid values are 1 to 60 seconds (default=10), applied after the first reconnection attempt. When a broken connection is detected, the client immediately attempts to reconnect; this is the first reconnection attempt and only occurs if ConnectRetryCount is greater than 0. If the first reconnection attempt fails and ConnectRetryCount is greater than 1, the client waits ConnectRetryInterval to try the second and subsequent reconnection attempts.
For additional information about idle connection resiliency, see [Technical Article - Idle Connection Resiliency](https://go.microsoft.com/fwlink/?LinkId=393996).|
-|Context Connection|'false'|`true` if an in-process connection to SQL Server should be made.|
|Current Language
-or-
Language|N/A|Sets the language used for database server warning or error messages.
The language name can be 128 characters or less.|
-|Data Source
-or-
Server
-or-
Address
-or-
Addr
-or-
Network Address|N/A|The name or network address of the instance of SQL Server to which to connect. The port number can be specified after the server name:
`server=tcp:servername, portnumber`
When specifying a local instance, always use (local). To force a protocol, add one of the following prefixes:
`np:(local), tcp:(local), lpc:(local)`
Beginning in .NET Framework 4.5, you can also connect to a LocalDB database as follows:
`server=(localdb)\\myInstance`
For more information about LocalDB, see [SqlClient Support for LocalDB](/dotnet/framework/data/adonet/sql/sqlclient-support-for-localdb).
**Data Source** must use the TCP format or the Named Pipes format.
TCP format is as follows:
- tcp:\\\ - tcp:\,\
The TCP format must start with the prefix "tcp:" and is followed by the database instance, as specified by a host name and an instance name. This format is not applicable when connecting to Azure SQL Database. TCP is automatically selected for connections to Azure SQL Database when no protocol is specified.
The host name MUST be specified in one of the following ways:
- NetBIOSName - IPv4Address - IPv6Address
The instance name is used to resolve to a particular TCP/IP port number on which a database instance is hosted. Alternatively, specifying a TCP/IP port number directly is also allowed. If both instance name and port number are not present, the default database instance is used.
The Named Pipes format is as follows:
- np:\\\\\pipe\\
The Named Pipes format MUST start with the prefix "np:" and is followed by a named pipe name.
The host name MUST be specified in one of the following ways:
- NetBIOSName - IPv4Address - IPv6Address
The pipe name is used to identify the database instance to which the .NET Framework application will be connected.
If the value of the **Network** key is specified, the prefixes "tcp:" and "np:" should not be specified. **Note:** You can force the use of TCP instead of shared memory, either by prefixing **tcp:** to the server name in the connection string, or by using **localhost**.|
-|Enclave Attestation Url|N/A|Gets or sets the enclave attestation Url to be used with enclave based Always Encrypted.|
-|Encrypt|'false'|When `true`, SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed. Recognized values are `true`, `false`, `yes`, and `no`. For more information, see [Connection String Syntax](/dotnet/framework/data/adonet/connection-string-syntax).
Beginning in .NET Framework 4.5, when `TrustServerCertificate` is false and `Encrypt` is true, the server name (or IP address) in a SQL Server SSL certificate must exactly match the server name (or IP address) specified in the connection string. Otherwise, the connection attempt will fail. For information about support for certificates whose subject starts with a wildcard character (*), see [Accepted wildcards used by server certificates for server authentication](https://support.microsoft.com/kb/258858).|
+|Data Source
-or-
Server
-or-
Address
-or-
Addr
-or-
Network Address|N/A|The name or network address of the instance of SQL Server to which to connect. The port number can be specified after the server name:
`server=tcp:servername, portnumber`
When specifying a local instance, always use (local). To force a protocol, add one of the following prefixes:
`np:(local), tcp:(local), lpc:(local)`
You can also connect to a LocalDB database as follows:
`server=(localdb)\\myInstance`
For more information about LocalDB, see [SqlClient Support for LocalDB](/sql/connect/ado-net/sql/sqlclient-support-localdb).
**Data Source** must use the TCP format or the Named Pipes format.
TCP format is as follows:
- tcp:\\\ - tcp:\,\
The TCP format must start with the prefix "tcp:" and is followed by the database instance, as specified by a host name and an instance name. This format is not applicable when connecting to Azure SQL Database. TCP is automatically selected for connections to Azure SQL Database when no protocol is specified.
The host name MUST be specified in one of the following ways:
- NetBIOSName - IPv4Address - IPv6Address
The instance name is used to resolve to a particular TCP/IP port number on which a database instance is hosted. Alternatively, specifying a TCP/IP port number directly is also allowed. If both instance name and port number are not present, the default database instance is used.
The Named Pipes format is as follows:
- np:\\\\\pipe\\
The Named Pipes format MUST start with the prefix "np:" and is followed by a named pipe name.
The host name MUST be specified in one of the following ways:
- NetBIOSName - IPv4Address - IPv6Address
The pipe name is used to identify the database instance to which the .NET application will connect.
If the value of the **Network** key is specified, the prefixes "tcp:" and "np:" should not be specified. **Note:** You can force the use of TCP instead of shared memory, either by prefixing **tcp:** to the server name in the connection string, or by using **localhost**.|
+|Enclave Attestation Url|N/A|Gets or sets the enclave attestation URL to be used with enclave based Always Encrypted.|
+|Encrypt|'true' in 4.0 and above
'false' in 3.x and below|Recognized values are: versions 1 - 4: `true`/`yes` and `false`/`no` versions 5+: `true`/`yes`/`mandatory`, `false`/`no`/`optional` and `strict`. When `true`, TLS encryption is used for all data sent between the client and server if the server has a certificate installed. When `strict`, TDS 8.0 TLS encryption is used and the `TrustServerCertificate` setting is ignored and treated as false. For more information, see [Connection String Syntax](/sql/connect/ado-net/connection-string-syntax).
When `Encrypt` is `mandatory` or `strict` and `TrustServerCertificate` is `false`, the server name (or IP address) in a server's certificate must exactly match the server name (or IP address) specified in the connection string. Otherwise, the connection attempt will fail. |
|Enlist|'true'|`true` indicates that the SQL Server connection pooler automatically enlists the connection in the creation thread's current transaction context.|
|Failover Partner|N/A|The name of the failover partner server where database mirroring is configured.
If the value of this key is "", then **Initial Catalog** must be present, and its value must not be "".
The server name can be 128 characters or less.
If you specify a failover partner but the failover partner server is not configured for database mirroring and the primary server (specified with the Server keyword) is not available, then the connection will fail.
If you specify a failover partner and the primary server is not configured for database mirroring, the connection to the primary server (specified with the Server keyword) will succeed if the primary server is available.|
+|Failover Partner SPN
-or-
FailoverPartnerSPN|N/A|The SPN for the failover partner. The default value is an empty string, which causes SqlClient to use the default, driver-generated SPN.
(Only available in v5.0+)|
+|Host Name In Certificate
-or-
HostNameInCertificate|N/A|The host name to use when validating the server certificate. When not specified, the server name from the Data Source is used for certificate validation.
(Only available in v5.0+)|
+|Server Certificate
-or-
ServerCertificate|N/A|The path to a certificate file to match against the SQL Server TLS/SSL certificate. The accepted certificate formats are PEM, DER, and CER. If specified, the SQL Server certificate is checked by verifying if the ServerCertificate provided is an exact match.
(Only available in v5.1+)|
|Initial Catalog
-or-
Database|N/A|The name of the database.
The database name can be 128 characters or less.|
|Integrated Security
-or-
Trusted_Connection|'false'|When `false`, User ID and Password are specified in the connection. When `true`, the current Windows account credentials are used for authentication.
Recognized values are `true`, `false`, `yes`, `no`, and `sspi` (strongly recommended), which is equivalent to `true`.
If User ID and Password are specified and Integrated Security is set to true, the User ID and Password will be ignored and Integrated Security will be used.
is a more secure way to specify credentials for a connection that uses SQL Server Authentication (`Integrated Security=false`).|
+|IP Address Preference
-or-
IPAddressPreference|IPv4First|The IP address family preference when establishing TCP connections. If `Transparent Network IP Resolution` (in .NET Framework) or `Multi Subnet Failover` is set to true, this setting has no effect. Supported values include:
Connection Lifetime|0|When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified by `Connection Lifetime`. This is useful in clustered configurations to force load balancing between a running server and a server just brought online.
A value of zero (0) causes pooled connections to have the maximum connection timeout.|
|Max Pool Size|100|The maximum number of connections that are allowed in the pool.
Valid values are greater than or equal to 1. Values that are less than **Min Pool Size** generate an error.|
|Min Pool Size|0|The minimum number of connections that are allowed in the pool.
Valid values are greater than or equal to 0. Zero (0) in this field means no minimum connections are initially opened.
Values that are greater than **Max Pool Size** generate an error.|
-|Multiple Active Result Sets
-or-
MultipleActiveResultSets|false|When `true`, an application can maintain multiple active result sets (MARS). When `false`, an application must process or cancel all result sets from one batch before it can execute any other batch on that connection.
Recognized values are `true` and `false`.
For more information, see [Multiple Active Result Sets (MARS)](/dotnet/framework/data/adonet/sql/multiple-active-result-sets-mars).|
-|Multi Subnet Failover
-or-
MultiSubnetFailover|false|Always specify `multiSubnetFailover=True` when connecting to the availability group listener of a SQL Server 2012 (or later) availability group or a SQL Server 2012 (or later) Failover Cluster Instance. `multiSubnetFailover=True` configures SqlClient to provide faster detection of and connection to the (currently) active server. Possible values are `Yes` and `No`, `True` and `False` or `1` and `0`. For example:
`MultiSubnetFailover=True`
The default is `False`. For more information about SqlClient's support for Always On AGs, see [SqlClient Support for High Availability, Disaster Recovery](/dotnet/framework/data/adonet/sql/sqlclient-support-for-high-availability-disaster-recovery).|
+|Multiple Active Result Sets
-or-
MultipleActiveResultSets|false|When `true`, an application can maintain multiple active result sets (MARS). When `false`, an application must process or cancel all result sets from one batch before it can execute any other batch on that connection.
Recognized values are `true` and `false`.
For more information, see [Multiple Active Result Sets (MARS)](/sql/connect/ado-net/sql/multiple-active-result-sets-mars).|
+|Multi Subnet Failover
-or-
MultiSubnetFailover|false|Always specify `multiSubnetFailover=True` when connecting to the availability group listener of a SQL Server 2012 (or later) availability group or a SQL Server 2012 (or later) Failover Cluster Instance. `multiSubnetFailover=True` configures SqlClient to provide faster detection of and connection to the (currently) active server. Possible values are `Yes` and `No`, `True` and `False` or `1` and `0`. For example:
`MultiSubnetFailover=True`
The default is `False`. For more information about SqlClient's support for Always On AGs, see [SqlClient Support for High Availability, Disaster Recovery](/sql/connect/ado-net/sql/sqlclient-support-high-availability-disaster-recovery).|
|Network Library
-or-
Network
-or-
Net|N/A|The network library used to establish a connection to an instance of SQL Server. Supported values include:
dbnmpntw (Named Pipes)
dbmsrpcn (Multiprotocol, Windows RPC)
dbmsadsn (Apple Talk)
dbmsgnet (VIA)
dbmslpcn (Shared Memory)
dbmsspxn (IPX/SPX)
dbmssocn (TCP/IP)
Dbmsvinn (Banyan Vines)
The corresponding network DLL must be installed on the system to which you connect. If you do not specify a network and you use a local server (for example, "." or "(local)"), shared memory is used. In this example, the network library is Win32 Winsock TCP/IP (dbmssocn), and 1433 is the port being used.
`Network Library=dbmssocn;Data Source=000.000.000.000,1433;`|
|Packet Size|8000|Size in bytes of the network packets used to communicate with an instance of SQL Server.
The packet size can be greater than or equal to 512 and less than or equal to 32768.|
|Password
-or-
PWD|N/A|The password for the SQL Server account logging on. Not recommended. To maintain a high level of security, we strongly recommend that you use the `Integrated Security` or `Trusted_Connection` keyword instead. is a more secure way to specify credentials for a connection that uses SQL Server Authentication.
The password must be 128 characters or less.|
-|Persist Security Info
-or-
PersistSecurityInfo|'false'|When set to `false` or `no` (strongly recommended), security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state. Resetting the connection string resets all connection string values including the password. Recognized values are `true`, `false`, `yes`, and `no`.|
+|Persist Security Info
-or-
PersistSecurityInfo|'false'|When set to `false` or `no` (strongly recommended), security-sensitive information, such as the password or access token, is not returned as part of the connection if the connection is open or has ever been in an open state. This property should only be set to `true` if your application has a specific need to read the password out of an already-opened database connection. The default value of `false` is the more secure setting; using `true` for this property opens your application to security risks such as accidentally logging or tracing the database password.
Resetting the connection string resets all connection string values including the password. Recognized values are `true`, `false`, `yes`, and `no`.|
|Pool Blocking Period
-or-
PoolBlockingPeriod|Auto|Sets the blocking period behavior for a connection pool. See property for details.|
|Pooling|'true'|When the value of this key is set to true, any newly created connection will be added to the pool when closed by the application. In a next attempt to open the same connection, that connection will be drawn from the pool.
Connections are considered the same if they have the same connection string. Different connections have different connection strings.
The value of this key can be "true", "false", "yes", or "no".|
|Replication|'false'|`true` if replication is supported using the connection.|
+|Server SPN
-or-
ServerSPN|N/A|The SPN for the data source. The default value is an empty string, which causes SqlClient to use the default, driver-generated SPN.
(Only available in v5.0+)|
|Transaction Binding|Implicit Unbind|Controls connection association with an enlisted `System.Transactions` transaction.
Possible values are:
`Transaction Binding=Implicit Unbind;`
`Transaction Binding=Explicit Unbind;`
Implicit Unbind causes the connection to detach from the transaction when it ends. After detaching, additional requests on the connection are performed in autocommit mode. The `System.Transactions.Transaction.Current` property is not checked when executing requests while the transaction is active. After the transaction has ended, additional requests are performed in autocommit mode.
If the system ends the transaction (in the scope of a using block) before the last command completes, it will throw .
Explicit Unbind causes the connection to remain attached to the transaction until the connection is closed or an explicit `SqlConnection.TransactionEnlist(null)` is called. Beginning in .NET Framework 4.0, changes to Implicit Unbind make Explicit Unbind obsolete. An `InvalidOperationException` is thrown if `Transaction.Current` is not the enlisted transaction or if the enlisted transaction is not active.|
|Transparent Network IP Resolution
-or-
TransparentNetworkIPResolution|See description.|When the value of this key is set to `true`, the application is required to retrieve all IP addresses for a particular DNS entry and attempt to connect with the first one in the list. If the connection is not established within 0.5 seconds, the application will try to connect to all others in parallel. When the first answers, the application will establish the connection with the respondent IP address.
If the `MultiSubnetFailover` key is set to `true`, `TransparentNetworkIPResolution` is ignored.
If the `Failover Partner` key is set, `TransparentNetworkIPResolution` is ignored.
The value of this key must be `true`, `false`, `yes`, or `no`.
A value of `yes` is treated the same as a value of `true`.
A value of `no` is treated the same as a value of `false`.
The default values are as follows:
`false` when:
Connecting to Azure SQL Database where the data source ends with:
.database.chinacloudapi.cn
.database.usgovcloudapi.net
.database.cloudapi.de
.database.windows.net
`Authentication` is 'Active Directory Password' or 'Active Directory Integrated'
`true` in all other cases.
|
-|Trust Server Certificate
-or-
TrustServerCertificate|'false'|When set to `true`, SSL is used to encrypt the channel when bypassing walking the certificate chain to validate trust. If TrustServerCertificate is set to `true` and Encrypt is set to `false`, the channel is not encrypted. Recognized values are `true`, `false`, `yes`, and `no`. For more information, see [Connection String Syntax](/dotnet/framework/data/adonet/connection-string-syntax).|
+|Trust Server Certificate
-or-
TrustServerCertificate|'false'|When set to `true`, TLS is used to encrypt the channel when bypassing walking the certificate chain to validate trust. If TrustServerCertificate is set to `true` and Encrypt is set to `false`, the channel is not encrypted. Recognized values are `true`, `false`, `yes`, and `no`. For more information, see [Connection String Syntax](/sql/connect/ado-net/connection-string-syntax).|
|Type System Version|N/A|A string value that indicates the type system the application expects. The functionality available to a client application is dependent on the version of SQL Server and the compatibility level of the database. Explicitly setting the type system version that the client application was written for avoids potential problems that could cause an application to break if a different version of SQL Server is used. **Note:** The type system version cannot be set for common language runtime (CLR) code executing in-process in SQL Server. For more information, see [SQL Server Common Language Runtime Integration](/dotnet/framework/data/adonet/sql/sql-server-common-language-runtime-integration).
Possible values are:
`Type System Version=SQL Server 2012;`
`Type System Version=SQL Server 2008;`
`Type System Version=SQL Server 2005;`
`Type System Version=Latest;`
`Type System Version=SQL Server 2012;` specifies that the application will require version 11.0.0.0 of Microsoft.SqlServer.Types.dll. The other `Type System Version` settings will require version 10.0.0.0 of Microsoft.SqlServer.Types.dll.
`Latest` is obsolete and should not be used. `Latest` is equivalent to `Type System Version=SQL Server 2008;`.|
-|User ID
-or-
UID
-or-|N/A|The SQL Server login account. Not recommended. To maintain a high level of security, we strongly recommend that you use the `Integrated Security` or `Trusted_Connection` keywords instead. is a more secure way to specify credentials for a connection that uses SQL Server Authentication.
The user ID must be 128 characters or less.|
+|User ID
-or-
UID
-or-
User|N/A|The SQL Server login account. Not recommended. To maintain a high level of security, we strongly recommend that you use the `Integrated Security` or `Trusted_Connection` keywords instead. is a more secure way to specify credentials for a connection that uses SQL Server Authentication.
The user ID must be 128 characters or less.|
|User Instance|'false'|A value that indicates whether to redirect the connection from the default SQL Server Express instance to a runtime-initiated instance running under the account of the caller.|
|Workstation ID
-or-
WSID|The local computer name|The name of the workstation connecting to SQL Server.
The ID must be 128 characters or less.|
- The following list contains the valid names for connection pooling values within the . For more information, see [SQL Server Connection Pooling (ADO.NET)](/dotnet/framework/data/adonet/sql-server-connection-pooling).
+ The following list contains the valid names for connection pooling values within the . For more information, see [SQL Server Connection Pooling (ADO.NET)](/sql/connect/ado-net/sql-server-connection-pooling).
- Connection Lifetime (or Load Balance Timeout)
@@ -587,7 +587,7 @@ The connection string contains .
> Universal data link (UDL) files are not supported for the .NET Framework Data Provider for SQL Server.
> [!CAUTION]
-> In this release, the application should use caution when constructing a connection string based on user input (for example when retrieving user ID and password information from a dialog box, and appending it to the connection string). The application should make sure that a user cannot embed additional connection string parameters in these values (for example, entering a password as "validpassword;database=somedb" in an attempt to attach to a different database). If you need to construct connection strings based on user input, use the new , which validates the connection string and helps to eliminate this problem. See [Connection String Builders](/dotnet/framework/data/adonet/connection-string-builders) for more information.
+> In this release, the application should use caution when constructing a connection string based on user input (for example when retrieving user ID and password information from a dialog box, and appending it to the connection string). The application should make sure that a user cannot embed additional connection string parameters in these values (for example, entering a password as "validpassword;database=somedb" in an attempt to attach to a different database). If you need to construct connection strings based on user input, use the new , which validates the connection string and helps to eliminate this problem. See [Connection String Builders](/sql/connect/ado-net/connection-string-builders) for more information.
@@ -652,8 +652,6 @@ The connection string contains .
- If is set on an open connection.
-- If is set when `Context Connection=true`.
-
- If is set when `Integrated Security = true`.
- If is set when the connection string uses `Password`.
@@ -692,14 +690,7 @@ The connection string contains .
The name of the instance of SQL Server to which to connect. The default value is an empty string. [!NOTE]
-> The property returns `null` if the connection string for the is "context connection=true".
-
-
-
+
## Examples
The following example creates a and displays some of its read-only properties.
@@ -725,7 +716,7 @@ The connection string contains .
method to enlist in a distributed transaction. Because it enlists a connection in a instance, **EnlistTransaction** takes advantage of functionality available in the namespace for managing distributed transactions, making it preferable to **EnlistDistributedTransaction** for this purpose. For more information, see [Distributed Transactions](/dotnet/framework/data/adonet/distributed-transactions).
+ You can use the method to enlist in a distributed transaction. Because it enlists a connection in a instance, **EnlistTransaction** takes advantage of functionality available in the namespace for managing distributed transactions, making it preferable to **EnlistDistributedTransaction** for this purpose. For more information, see [Distributed Transactions](/sql/connect/ado-net/distributed-transactions).
You can continue to enlist in an existing distributed transaction using the **EnlistDistributedTransaction** method if auto-enlistment is disabled. Enlisting in an existing distributed transaction makes sure that, if the transaction is committed or rolled back, modifications made by the code at the data source are also committed or rolled back.
@@ -741,7 +732,7 @@ The connection string contains .
method to enlist in a distributed transaction. Because it enlists a connection in a instance, **EnlistTransaction** takes advantage of functionality available in the namespace for managing distributed transactions, making it preferable to **EnlistDistributedTransaction**, which uses a **System.EnterpriseServices.ITransaction** object. It also has slightly different semantics: once a connection is explicitly enlisted on a transaction, it cannot be unenlisted or enlisted in another transaction until the first transaction finishes. For more information about distributed transactions, see [Distributed Transactions](/dotnet/framework/data/adonet/distributed-transactions).
+ You can use the method to enlist in a distributed transaction. Because it enlists a connection in a instance, **EnlistTransaction** takes advantage of functionality available in the namespace for managing distributed transactions, making it preferable to **EnlistDistributedTransaction**, which uses a **System.EnterpriseServices.ITransaction** object. It also has slightly different semantics: once a connection is explicitly enlisted on a transaction, it cannot be unenlisted or enlisted in another transaction until the first transaction finishes. For more information about distributed transactions, see [Distributed Transactions](/sql/connect/ado-net/distributed-transactions).
]]>
@@ -759,7 +750,7 @@ The connection string contains .
> [!NOTE]
> An error with a severity level of 17 or above that causes the server to stop processing the command needs to be handled as an exception. In this case, an exception is thrown regardless of how the error is handled in the event.
- For more information on working with events, see [Connection Events](/dotnet/framework/data/adonet/connection-events). For more information on errors generated by the SQL Server engine, see [Database Engine Errors](/sql/relational-databases/errors-events/database-engine-events-and-errors).
+ For more information on working with events, see [Connection Events](/sql/connect/ado-net/connection-events). For more information on errors generated by the SQL Server engine, see [Database Engine Errors](/sql/relational-databases/errors-events/database-engine-events-and-errors).
]]>
@@ -776,7 +767,7 @@ The connection string contains .
- Returns schema information for the data source of this . For more information about scheme, see [SQL Server Schema Collections](/dotnet/framework/data/adonet/sql-server-schema-collections).
+ Returns schema information for the data source of this . For more information about scheme, see [SQL Server Schema Collections](/sql/connect/ado-net/sql-server-schema-collections).A that contains schema information.To be added.
@@ -903,7 +894,7 @@ GO
The event occurs when a message with a severity of 10 or less is returned by SQL Server. Messages that have a severity between 11 and 20 raise an error and messages that have a severity over 20 causes the connection to close. For more information on SQL Server error levels, see [Database Engine Error Severities](/sql/relational-databases/errors-events/database-engine-error-severities).
- For more information and an example, see [Connection Events](/dotnet/framework/data/adonet/connection-events).
+ For more information and an example, see [Connection Events](/sql/connect/ado-net/connection-events).
]]>
@@ -1001,14 +992,12 @@ GO
A call to will attempt to cancel or close the corresponding call.
- For more information about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/dotnet/framework/data/adonet/asynchronous-programming).
+ For more information about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/sql/connect/ado-net/asynchronous-programming).
]]>
Calling more than once for the same instance before task completion.
- is specified in the connection string.
-
A connection was not available from the connection pool before the connection time out elapsed.Any error returned by SQL Server that occurred while opening the connection.
@@ -1036,8 +1025,12 @@ GO
- Custom column encryption key provider dictionary
- Registers the column encryption key store providers. This function should only be called once in an app. This does shallow copying of the dictionary so that the app cannot alter the custom provider list once it has been set.
+ Dictionary of custom column encryption key store providers
+
+ Registers the column encryption key store providers. This function should only be called once in an app. This does shallow copying of the dictionary so that the app cannot alter the custom provider list once it has been set.
+
+ The built-in column master key store providers that are available for the Windows Certificate Store, CNG Store and CSP are pre-registered.
+
+
+ A null dictionary was provided.
+
+ -or-
+
+ A string key in the dictionary was null or empty.
+
+ -or-
+
+ A value in the dictionary was null.
+
+
+ A string key in the dictionary started with "MSSQL_". This prefix is reserved for system providers.
+
+
+ This function was called more than once.
+
+
+ Dictionary of custom column encryption key providers
+ Registers the encryption key store providers on the instance. If this function has been called, any providers registered using the static methods will be ignored. This function can be called more than once. This does shallow copying of the dictionary so that the app cannot alter the custom provider list once it has been set.
+
+ A null dictionary was provided.
+
+ -or-
+
+ A string key in the dictionary was null or empty.
+
+ -or-
+
+ A value in the dictionary was null.
+
+
+ A string key in the dictionary started with "MSSQL_". This prefix is reserved for system providers.
+
+
+
+
+
+
+ Gets or sets a value that specifies the
+
+ object bound to this command.
+
+
+ When set to null (default), the default non-retriable provider will be applied.
+
+
+ type.
+2. Create a by using one of the following static methods of the class:
+ -
+ -
+ -
+ -
+3. Assign the object to the `RetryLogicProvider` property.
+
+> [!NOTE]
+> Detecting retriable exceptions is a vital part of the retry pattern. Before applying retry logic, it is important to investigate exceptions and choose a retry provider that best fits your scenario. First, log your exceptions and find transient faults.
+
+> [!NOTE]
+> The connection **timeout** restarts for each execution of a connection open. There is no timing overlap between these two actions.
+
+> [!NOTE]
+> The default retry logic provider is not enabled unless it is configured in an application configuration file. For more information, see [Configurable retry logic and configuration file](/sql/connect/ado-net/configurable-retry-logic-config-file-sqlclient).
+
+## Example
+The following sample tries to open a connection to an invalid database to simulate a condition that the database service is temporarily unavailable . You should manually create the database while the tries to establish the connection.
+
+[!code-csharp[SqlConfigurableRetryLogic_OpenConnection#1](~/../sqlclient/doc/samples/SqlConfigurableRetryLogic_OpenConnection.cs#1)]
+
+]]>
+
+ If statistics gathering is enabled, all values are reset to zero.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionAttestationProtocol.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionAttestationProtocol.xml
index d5f32ef2d3..db98ad4fdf 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionAttestationProtocol.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionAttestationProtocol.xml
@@ -13,10 +13,10 @@
Attestation portocol for Azure Attestation Service1
-
- Attestation protocol for Simulator
+
+ Attestation protocol for no attestation. Only compatible with Virtualization-based security (VBS) enclaves. An Enclave Attestation Url is not required when using this protocol.2
-
+
Attestation protocol for Host Guardian Service3
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml
new file mode 100644
index 0000000000..35b8d24ab6
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionEncryptOption.xml
@@ -0,0 +1,75 @@
+
+
+
+
+ These options are used to control encryption behavior of the communication between the server and the client.
+
+ property. When converting from a boolean, a value of `true` converts to and a value of `false` converts to . When converting to a boolean, , , and `null` convert to `true` and converts `false`.
+
+ ]]>
+
+
+
+
+ Converts the specified string representation of a logical value to its equivalent.
+
+ A string containing the value to convert.
+
+ An object that is equivalent to contained in .
+
+
+ Throws exception if provided is not convertible to type.
+
+
+
+
+ Converts the specified string representation of a logical value to its equivalent and returns a value that indicates whether the conversion succeeded.
+
+ A string containing the value to convert.
+
+ An object that is equivalent to contained in . if conversion fails.
+
+
+ if the parameter was converted successfully; otherwise, .
+
+ This method does not throw an exception if conversion fails.
+
+
+ Specifies that TLS encryption is optional when connecting to the server. If the server requires encryption, encryption will be negotiated.
+
+
+ Specifies that TLS encryption is required when connecting to the server. If the server doesn't support encryption, the connection will fail.
+
+
+ Enables and requires TDS 8.0, TLS encryption to the server. If the server doesn't support TDS 8.0, TLS encryption, the connection will fail.
+
+
+ The boolean value to be used for implicit comparison.
+
+ Enables implicit converstion of a boolean to a . A value of converts to . A value of converts to .
+
+
+
+ The value to be used for implicit comparison.
+
+ Enables implicit converstion of a to a boolean. and convert to . converts to .
+
+
+
+ Returns the string value of .
+
+
+
+ Compares the representation of to another .
+
+
+
+
+ Returns the hash code of the value.
+
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionIPAddressPreference.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionIPAddressPreference.xml
new file mode 100644
index 0000000000..e713cb776b
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionIPAddressPreference.xml
@@ -0,0 +1,40 @@
+
+
+
+
+ Specifies a value for IP address preference during a TCP connection.
+
+
+
+
+
+
+
+ Specifies a value for IP address preference during a TCP connection.
+
+
+
+
+
+
+ Connects using IPv4 address(es) first. If the connection fails, try IPv6 address(es), if provided. This is the default value.
+ 0
+
+
+ Connect using IPv6 address(es) first. If the connection fails, try IPv4 address(es), if available.
+ 1
+
+
+ Connects with IP addresses in the order the underlying platform or operating system provides them.
+ 2
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml
index 98d4d5cc70..82f7aa8ec9 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml
@@ -86,20 +86,30 @@ Integrated Security=True
The supplied is not valid.
- Declares the application workload type when connecting to a database in an SQL Server Availability Group. You can set the value of this property with . For more information about SqlClient support for Always On Availability Groups, see [SqlClient Support for High Availability, Disaster Recovery](/dotnet/framework/data/adonet/sql/sqlclient-support-for-high-availability-disaster-recovery).
- Returns the current value of the property (a value of type ).
- To be added.
- ADO.NET Overview
+ Declares the application workload type when connecting to a database in an SQL Server Availability Group. You can set the value of this property with . For more information about SqlClient support for Always On Availability Groups, see [SqlClient Support for High Availability, Disaster Recovery](/sql/connect/ado-net/sql/sqlclient-support-high-availability-disaster-recovery).
+ Returns the current value of the property.
+
+
+
+ Overview of the SqlClient driverGets or sets the name of the application associated with the connection string.
- The name of the application, or ".NET SqlClient Data Provider" if no name has been supplied.
+ The name of the application. If no name has been supplied, "Framework Microsoft SqlClient Data Provider" when running on .NET Framework and "Core Microsoft SqlClient Data Provider" otherwise.To set the value to null, use .
-
- Gets or sets a Boolean value that indicates whether asynchronous processing is allowed by the connection created by using this connection string.
- The value of the property, or if no value has been supplied.
-
- object, this key/value pair must be included within the connection string of the associated object.
-
-
-
-## Examples
- The following example retrieves a connection string and verifies that the connection string is configured to allow for asynchronous processing. (In this case, the string comes from a procedure within the application, but in a production application, the connection string might come from a configuration file, or some other source.) Then, the example performs an asynchronous operation, updating values within a sample database on a background thread.
-
- [!code-csharp[SqlConnectionStringBuilder_AsynchronousProcessing#1](~/../sqlclient/doc/samples/SqlConnectionStringBuilder_AsynchronousProcessing.cs#1)]
-
- ]]>
-
-
-
-
- Gets or sets a string that contains the name of the primary data file. This includes the full path name of an attachable database.The value of the property, or if no value has been supplied.
@@ -151,9 +139,20 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security
This property corresponds to the "AttachDBFilename", "extended properties", and "initial file name" keys within the connection string.
`AttachDBFilename` is only supported for primary data files with an .mdf extension.
-
+
+ If the value of the AttachDBFileName key is specified in the connection string, the database is attached and becomes the default database for the connection.
+
+ If this key is not specified and if the database was previously attached, the database will not be reattached. The previously attached database will be used as the default database for the connection.
+
+ If this key is specified together with the AttachDBFileName key, the value of this key will be used as the alias. However, if the name is already used in another attached database, the connection will fail.
+
+ The path may be absolute or relative by using the DataDirectory substitution string. If DataDirectory is used, the database file must exist within a subdirectory of the directory pointed to by the substitution string. **Note:** Remote server, HTTP, and UNC path names are not supported.
+
+ The database name must be specified with the keyword 'database' (or one of its aliases) as in the following:
+
+ `"AttachDbFileName=|DataDirectory|\data\YourDB.mdf;integrated security=true;database=YourDatabase"`
+
An error will be generated if a log file exists in the same directory as the data file and the 'database' keyword is used when attaching the primary data file. In this case, remove the log file. Once the database is attached, a new log file will be automatically generated based on the physical path.
-
## Examples
@@ -165,12 +164,26 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security
To set the value to null, use .Working with Connection Strings
- ADO.NET Overview
+ Overview of the SqlClient driver
+
+ Gets or sets the value of Attestation Protocol.
+ The attestation protocol.
+
- Gets the authentication of the connection string.
- The authentication of the connection string.
- To be added.
+ Gets or sets the authentication method used for [Connecting to SQL Database By Using Azure Active Directory Authentication](https://azure.microsoft.com/documentation/articles/sql-database-aad-authentication/#7-connect-to-your-database-by-using-azure-active-directory-identities).
+ The authentication method of the connection string.
+
+
+ Clears the contents of the instance.
@@ -179,7 +192,6 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security
## Remarks
The method removes all key/value pairs from the , and resets all corresponding properties. This includes setting the property to 0, and setting the property to an empty string.
-
## Examples
@@ -192,8 +204,7 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security
Gets or sets the column encryption settings for the connection string builder.
- The column encryption settings for the connection string builder.
- To be added.
+ The column encryption settings for the connection string builder.This property enables or disables [Always Encrypted](/sql/relational-databases/security/encryption/always-encrypted-database-engine) functionality for the connection.
@@ -207,6 +218,8 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security
## Remarks
This property corresponds to the "Command Timeout" key within the connection string.
+
+ Valid values are greater than or equal to 0 and less than or equal to 2147483647.
]]>
@@ -239,8 +252,9 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security
- Amount of time (in seconds) between each reconnection attempt after identifying that there was an idle connection failure. This must be an integer between 1 and 60. The default is 10 seconds. An will be thrown if set to a value outside of the allowed range.
+ Amount of time (in seconds) between each reconnection attempt after identifying that there was an idle connection failure. This must be an integer between 1 and 60. The default is 10 seconds.Amount of time (in seconds) between each reconnection attempt after identifying that there was an idle connection failure.
+ Value is outside of the allowed range.
connection string.
+This value is applied after the first reconnection attempt. When a broken connection is detected, the client immediately attempts to reconnect; this is the first reconnection attempt and only occurs if `ConnectRetryCount` is greater than 0. If the first reconnection attempt fails and `ConnectRetryCount` is greater than 1, the client waits `ConnectRetryInterval` to try the second and subsequent reconnection attempts.
+
]]>
@@ -263,6 +279,7 @@ Modified: Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security
When opening a connection to a Azure SQL Database, set the connection timeout to 30 seconds.
+ Valid values are greater than or equal to 0 and less than or equal to 2147483647.
## Examples
@@ -306,7 +323,7 @@ False
is null ( in Visual Basic)
- Gets or sets a value that indicates whether a client/server or in-process connection to SQL Server should be made.
+ Obsolete. Gets or sets a value that indicates whether a client/server or in-process connection to SQL Server should be made.The value of the property, or if none has been supplied.
- Gets or sets the SQL Server Language record name.
+ Gets or sets the language used for database server warning or error messages..The value of the property, or if no value has been supplied.
@@ -342,7 +361,40 @@ False
## Remarks
This property corresponds to the "Data Source", "server", "address", "addr", and "network address" keys within the connection string. Regardless of which of these values has been supplied within the supplied connection string, the connection string created by the `SqlConnectionStringBuilder` will use the well-known "Data Source" key.
-
+The port number can be specified after the server name: `server=tcp:servername, portnumber`.
+
+When specifying a local instance, always use (local). To force a protocol, add one of the following prefixes:`np:(local), tcp:(local), lpc:(local)`.
+
+You can also connect to a LocalDB database as follows: `server=(localdb)\\myInstance`. For more information about LocalDB, see [SqlClient Support for LocalDB](/sql/connect/ado-net/sql/sqlclient-support-localdb).
+**Data Source** must use the TCP format or the Named Pipes format. TCP format is as follows:
+
+- tcp:\\\
+- tcp:\,\
+
+The TCP format must start with the prefix "tcp:" and is followed by the database instance, as specified by a host name and an instance name. This format is not applicable when connecting to Azure SQL Database. TCP is automatically selected for connections to Azure SQL Database when no protocol is specified.
+
+The host name MUST be specified in one of the following ways:
+- NetBIOSName
+- IPv4Address
+- IPv6Address
+
+The instance name is used to resolve to a particular TCP/IP port number on which a database instance is hosted. Alternatively, specifying a TCP/IP port number directly is also allowed. If both instance name and port number are not present, the default database instance is used.
+
+The Named Pipes format is as follows:
+- np:\\\\\pipe\\
+
+The Named Pipes format MUST start with the prefix "np:" and is followed by a named pipe name.
+
+The host name MUST be specified in one of the following ways:
+
+- NetBIOSName
+- IPv4Address
+- IPv6Address
+
+The pipe name is used to identify the database instance to which the .NET application will connect.
+
+If the value of the **Network** key is specified, the prefixes "tcp:" and "np:" should not be specified. **Note:** You can force the use of TCP instead of shared memory, either by prefixing **tcp:** to the server name in the connection string, or by using **localhost**.
+
## Examples
The following example demonstrates that the class converts synonyms for the "Data Source" connection string key into the well-known key:
@@ -354,27 +406,30 @@ False
To set the value to null, use .
- Gets or sets the enclave attestation Url to be used with enclave based Always Encrypted.
- The enclave attestation Url.
- To be added.
+ Gets or sets the enclave attestation URL to be used with enclave based Always Encrypted.
+ The enclave attestation URL.
-
- Set/Get the value of Attestation Protocol.
- Returns Attestation Protocol.
-
- Gets or sets a Boolean value that indicates whether SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed.
- The value of the property, or if none has been supplied.
+ Gets or sets a value since version 5.0 or a value for the earlier versions that indicates whether TLS encryption is required for all data sent between the client and server.
+ The value of the property., or `true`, the server name (or IP address) in a server's TLS certificate must exactly match the server name (or IP address) specified in the connection string. Otherwise, the connection attempt will fail. For information about support for certificates whose subject starts with a wildcard character (*), see [Enable encrypted connections to the Database Engine](/sql/database-engine/configure-windows/enable-encrypted-connections-to-the-database-engine#certificate-requirements).
+
+> [!NOTE]
+> Starting from **version 4.0**, the default value of the property `Encrypt` is set to `true` while it is `false` for earlier versions.
+
+> [!NOTE]
+> Starting from **version 5.0**, the data type is updated to , and the default value of the `Encrypt` property is set to .
+
]]>Working with Connection Strings
- ADO.NET Overview
+ Overview of the SqlClient driverGets or sets a Boolean value that indicates whether the SQL Server connection pooler automatically enlists the connection in the creation thread's current transaction context.
@@ -391,9 +446,60 @@ False
Gets or sets the name or address of the partner server to connect to if the primary server is down.The value of the property, or if none has been supplied.
- To be added.To set the value to null, use .
+
+
+
+
+ Gets or sets the service principal name (SPN) of the failover partner for the connection.
+
+ The value of the property, or if none has been supplied.
+
+
+
+ [!NOTE]
+> This property only applies when using Integrated Security mode, otherwise it is ignored.
+
+ ]]>
+
+
+
+
+ Gets or sets the host name to use when validating the server certificate for the connection. When not specified, the server name from the `Data Source` is used for certificate validation. (Only available in v5.0+)
+
+ The value of the property, or if none has been supplied.
+
+
+
+ [!NOTE]
+> This property only applies when using `Encrypt` in or mode, otherwise it is ignored.
+
+ ]]>
+
+
+
To be added.
To be added.
@@ -408,7 +514,7 @@ False
## Remarks
This property corresponds to the "Initial Catalog" and "database" keys within the connection string.
-
+ The database name can be 128 characters or less.
## Examples
The following example creates a simple connection string and then uses the class to add the name of the database to the connection string. The code displays the contents of the property, just to verify that the class was able to convert from the synonym ("Database") to the appropriate property value.
@@ -428,6 +534,9 @@ False
## Remarks
This property corresponds to the "Integrated Security" and "trusted_connection" keys within the connection string.
+ If User ID and Password are specified and Integrated Security is set to true, the User ID and Password will be ignored and Integrated Security will be used.
+
+ is a more secure way to specify credentials for a connection that uses SQL Server Authentication (`Integrated Security=false`).
## Examples
@@ -441,13 +550,25 @@ False
]]>
+
+ Gets or sets the IP address family preference when establishing TCP connections.
+ Returns the IP address preference.
+
+
+
+ Gets a value that indicates whether the has a fixed size. in every case, because the supplies a fixed-size collection of key/value pairs.To be added.Working with Connection Strings
- ADO.NET Overview
+ Overview of the SqlClient driver
The key of the item to get or set.
@@ -503,6 +624,10 @@ False
## Remarks
This property corresponds to the "Load Balance Timeout" and "connection lifetime" keys within the connection string.
+When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified by `Connection Lifetime`. This is useful in clustered configurations to force load balancing between a running server and a server just brought online.
+
+A value of zero (0) causes pooled connections to have the maximum connection timeout.
+
]]>
@@ -542,7 +667,7 @@ False
## Examples
- The following example explicitly disables the Multiple Active Result Sets feature.
+ The following example explicitly enables the Multiple Active Result Sets feature.
[!code-csharp[SqlConnectionStringBuilder_MultipleActiveResultSets.MARS#1](~/../sqlclient/doc/samples/SqlConnectionStringBuilder_MultipleActiveResultSets.cs#1)]
@@ -550,9 +675,16 @@ False
- If your application is connecting to an AlwaysOn availability group (AG) on different subnets, setting MultiSubnetFailover=true provides faster detection of and connection to the (currently) active server. For more information about SqlClient support for Always On Availability Groups, see [SqlClient Support for High Availability, Disaster Recovery](/dotnet/framework/data/adonet/sql/sqlclient-support-for-high-availability-disaster-recovery).
+ If your application is connecting to an AlwaysOn availability group (AG) on different subnets, setting MultiSubnetFailover=true provides faster detection of and connection to the (currently) active server. For more information about SqlClient support for Always On Availability Groups, see [SqlClient Support for High Availability, Disaster Recovery](/sql/connect/ado-net/sql/sqlclient-support-high-availability-disaster-recovery).Returns indicating the current value of the property.
- To be added.
+
+
+ Gets or sets a string that contains the name of the network library used to establish a connection to the SQL Server.
@@ -578,6 +710,8 @@ False
## Remarks
This property corresponds to the "Packet Size" key within the connection string.
+The packet size can be greater than or equal to 512 and less than or equal to 32768.
+
]]>
@@ -589,9 +723,12 @@ False
## Remarks
This property corresponds to the "Password" and "pwd" keys within the connection string.
+
+Setting this property is not recommended. To maintain a high level of security, we strongly recommend that you use the `Integrated Security` or `Trusted_Connection` keyword instead. is a more secure way to specify credentials for a connection that uses SQL Server Authentication.
If has not been set and you retrieve the value, the return value is . To reset the password for the connection string, pass null to the Item property.
+The password must be 128 characters or less.
## Examples
@@ -604,7 +741,7 @@ False
The password was incorrectly set to null. See code sample below.
- Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state.
+ Gets or sets a Boolean value indicating if security-sensitive information, such as the password or access token, should be returned as part of the connection string on a connection created with this after that connection has ever been in an open state. This property should only be set to if your application has a specific need to read the password out of an already-opened database connection. The default value of is the more secure setting; using for this property opens your application to security risks such as accidentally logging or tracing the database password.The value of the property, or if none has been supplied.
@@ -641,6 +780,8 @@ False
## Remarks
This property corresponds to the "Pooling" key within the connection string.
+Connections are considered the same if they have the same connection string. Different connections have different connection strings.
+
]]>
@@ -659,14 +800,13 @@ False
|Key|Default value|
|---------|-------------------|
-|Application Name|".Net SqlClient Data Provider"|
-|Asynchronous Processing|False|
+|Application Name|"Framework Microsoft SqlClient Data Provider" when running on .NET Framework. "Core Microsoft SqlClient Data Provider" otherwise.|
|AttachDBFilename|Empty string|
|Connection Timeout|15|
-|Context Connection|False|
+|Context Connection(Obsolete)|False|
|Current Language|Empty string|
|Data Source|Empty string|
-|Encrypt|False|
+|Encrypt|False in versions prior to 4.0, True in versions 4.0 and up|
|Enlist|True|
|Failover Partner|Empty string|
|Initial Catalog|Empty string|
@@ -721,6 +861,44 @@ Database = AdventureWorks
]]>
+
+ Gets or sets the path to a certificate file to match against the SQL Server TLS/SSL certificate for the connection. The accepted certificate formats are PEM, DER, and CER. If specified, the SQL Server certificate is checked by verifying if the `ServerCertificate` provided is an exact match. (Only available in v5.1+)
+
+ The value of the property, or if none has been supplied.
+
+
+
+ [!NOTE]
+> This property only applies when using `Encrypt` in or mode, otherwise it is ignored.
+
+ ]]>
+
+
+
+
+ Gets or sets the service principal name (SPN) of the data source.
+
+ The value of the property, or if none has been supplied.
+
+
+
+ [!NOTE]
+> This property only applies when using Integrated Security mode, otherwise it is ignored.
+
+ ]]>
+
+
+
The key to locate in the .
Indicates whether the specified key exists in this instance.
@@ -737,7 +915,7 @@ Database = AdventureWorks
Gets or sets a string value that indicates how the connection maintains its association with an enlisted transaction.
- The value of the property, or if none has been supplied.
+ The value of the property, or `Implicit Unbind` if none has been supplied.Gets or sets a value that indicates whether the channel will be encrypted while bypassing walking the certificate chain to validate trust.
- A . Recognized values are , , , and .
+ A boolean. The default is `false`. is a more secure way to specify credentials for a connection that uses SQL Server Authentication.
+
+ The user ID must be 128 characters or less.
+
]]>To set the value to null, use .
@@ -888,7 +1072,7 @@ Unable to retrieve value for null key.
This property corresponds to the "User Instance" key within the connection string.
> [!NOTE]
-> This feature is available only with the SQL Server Express Edition. For more information on user instances, see [SQL Server Express User Instances](/dotnet/framework/data/adonet/sql/sql-server-express-user-instances).
+> This feature is available only with the SQL Server Express Edition. For more information on user instances, see [SQL Server Express User Instances](/sql/connect/ado-net/sql/sql-server-express-user-instances).
]]>
@@ -922,7 +1106,9 @@ Unable to retrieve value for null key.
## Remarks
This property corresponds to the "Workstation ID" and "wsid" keys within the connection string.
-
+
+ The ID must be 128 characters or less.
+
]]>
To set the value to null, use .
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlCredential.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlCredential.xml
index 41ff58e6a5..41caafa87f 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlCredential.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlCredential.xml
@@ -14,7 +14,7 @@
to get or set a connection's object. Use to change the password for a object. For information on how a object affects connection pool behavior, see [SQL Server Connection Pooling (ADO.NET)](/dotnet/framework/data/adonet/sql-server-connection-pooling).
+ Use to get or set a connection's object. Use to change the password for a object. For information on how a object affects connection pool behavior, see [SQL Server Connection Pooling (ADO.NET)](/sql/connect/ado-net/sql-server-connection-pooling).
An exception will be raised if a non-null object is used in a connection with any of the following connection string keywords:
@@ -24,8 +24,6 @@
- `User ID`
-- `Context Connection = true`
-
The following sample connects to a SQL Server database using :
```
@@ -70,19 +68,19 @@ using (SqlConnection conn = new SqlConnection(connString.ConnectionString))
]]>
- ADO.NET Overview
+ Overview of the SqlClient driverGets the password component of the object.The password component of the object.To be added.
- ADO.NET Overview
+ Overview of the SqlClient driverGets the user ID component of the object.The user ID component of the object.To be added.
- ADO.NET Overview
+ Overview of the SqlClient driver
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlDataAdapter.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlDataAdapter.xml
index 6d4ace23d3..6fb16341ef 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlDataAdapter.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlDataAdapter.xml
@@ -7,7 +7,7 @@
, serves as a bridge between a and SQL Server for retrieving and saving data. The provides this bridge by mapping , which changes the data in the to match the data in the data source, and , which changes the data in the data source to match the data in the , using the appropriate Transact-SQL statements against the data source. The update is performed on a by-row basis. For every inserted, modified, and deleted row, the method determines the type of change that has been performed on it (`Insert`, `Update`, or `Delete`). Depending on the type of change, the `Insert`, `Update`, or `Delete` command template executes to propagate the modified row to the data source. When the fills a , it creates the necessary tables and columns for the returned data if they do not already exist. However, primary key information is not included in the implicitly created schema unless the property is set to . You may also have the create the schema of the , including primary key information, before filling it with data using `FillSchema`. For more information, see [Adding Existing Constraints to a DataSet](/dotnet/framework/data/adonet/adding-existing-constraints-to-a-dataset).
+ The , serves as a bridge between a and SQL Server for retrieving and saving data. The provides this bridge by mapping , which changes the data in the to match the data in the data source, and , which changes the data in the data source to match the data in the , using the appropriate Transact-SQL statements against the data source. The update is performed on a by-row basis. For every inserted, modified, and deleted row, the method determines the type of change that has been performed on it (`Insert`, `Update`, or `Delete`). Depending on the type of change, the `Insert`, `Update`, or `Delete` command template executes to propagate the modified row to the data source. When the fills a , it creates the necessary tables and columns for the returned data if they do not already exist. However, primary key information is not included in the implicitly created schema unless the property is set to . You may also have the create the schema of the , including primary key information, before filling it with data using `FillSchema`. For more information, see [Adding Existing Constraints to a DataSet](/sql/connect/ado-net/add-existing-constraints-to-dataset).
is used in conjunction with and to increase performance when connecting to a SQL Server database.
@@ -186,7 +186,7 @@
, if this property is not set and primary key information is present in the , the can be generated automatically if you set the property and use the . Then, any additional commands that you do not set are generated by the . This generation logic requires key column information to be present in the . For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+ During , if this property is not set and primary key information is present in the , the can be generated automatically if you set the property and use the . Then, any additional commands that you do not set are generated by the . This generation logic requires key column information to be present in the . For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
When is assigned to a previously created , the is not cloned. The maintains a reference to the previously created object.
@@ -238,7 +238,7 @@
, if this property is not set and primary key information is present in the , the can be generated automatically if you set the property and use the . Then, any additional commands that you do not set are generated by the . This generation logic requires key column information to be present in the . For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+ During , if this property is not set and primary key information is present in the , the can be generated automatically if you set the property and use the . Then, any additional commands that you do not set are generated by the . This generation logic requires key column information to be present in the . For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
When is assigned to a previously created , the is not cloned. The maintains a reference to the previously created object.
@@ -476,7 +476,7 @@
, if this property is not set and primary key information is present in the , the can be generated automatically if you set the property and use the . Then, any additional commands that you do not set are generated by the . This generation logic requires key column information to be present in the . For more information, see [Generating Commands with CommandBuilders](/dotnet/framework/data/adonet/generating-commands-with-commandbuilders).
+ During , if this property is not set and primary key information is present in the , the can be generated automatically if you set the property and use the . Then, any additional commands that you do not set are generated by the . This generation logic requires key column information to be present in the . For more information, see [Generating Commands with CommandBuilders](/sql/connect/ado-net/generate-commands-with-commandbuilders).
When is assigned to a previously created , the is not cloned. The maintains a reference to the previously created object.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml
index 9f61a25a03..b0ce159fbf 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlDataReader.xml
@@ -319,22 +319,24 @@
Synchronously gets the value of the specified column as a type. is the asynchronous version of this method.The returned type object.
-
+ .|||
+|Boolean|Byte|Char|DateOnly (.NET 6 or later)|
+|DateTime|DateTimeOffset|Decimal|Double|
+|Float|Guid|Int16|Int32|
+|Int64|SqlBoolean|SqlByte|SqlDateTime|
+|SqlDecimal|SqlDouble|SqlGuid|SqlInt16|
+|SqlInt32|SqlInt64|SqlMoney|SqlSingle|
+|SqlString|Stream|String|TextReader|
+|TimeOnly (.NET 6 or later)|XmlReader||UDT, which can be any CLR type marked with .|
- For more information, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For more information, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
]]>
@@ -359,22 +361,24 @@
Asynchronously gets the value of the specified column as a type. is the synchronous version of this method.The returned type object.
-
+ .|||
+|Boolean|Byte|Char|DateOnly (.NET 6 or later)|
+|DateTime|DateTimeOffset|Decimal|Double|
+|Float|Guid|Int16|Int32|
+|Int64|SqlBoolean|SqlByte|SqlDateTime|
+|SqlDecimal|SqlDouble|SqlGuid|SqlInt16|
+|SqlInt32|SqlInt64|SqlMoney|SqlSingle|
+|SqlString|Stream|String|TextReader|
+|TimeOnly (.NET 6 or later)|XmlReader||UDT, which can be any CLR type marked with .|
- For more information, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For more information, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
]]>
@@ -386,9 +390,7 @@
Tried to read a previously-read column in sequential mode.
- There was an asynchronous operation in progress. This applies to all Get* methods when running in sequential mode, as they could be called while reading a stream.
-
- is specified in the connection string.
+ There was an asynchronous operation in progress. This applies to all Get* methods when running in sequential mode, as they could be called while reading a stream.
Trying to read a column that does not exist.The value of the column was null ( == ), retrieving a non-SQL type.
@@ -530,7 +532,7 @@
method returns metadata about each column in the following order:
+ The method returns the following metadata about each column:
|DataReader column|Description|
|-----------------------|-----------------|
@@ -835,9 +837,7 @@
- WriteTimeout
- When the connection property `ContextConnection=true`, only supports synchronous data retrieval for both sequential () and non-sequential () access.
-
- For more information, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For more information, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
]]>
@@ -891,9 +891,7 @@
will raise an exception when used on an object returned by when is in effect.
- When the connection property `ContextConnection=true`, only supports synchronous data retrieval for both sequential () and non-sequential () access.
-
- For more information, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For more information, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
]]>
@@ -988,7 +986,7 @@
will raise an exception when used on an object returned by when is in effect.
- For more information, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For more information, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
]]>
@@ -1065,7 +1063,7 @@
@@ -1077,9 +1075,8 @@
Trying to read a previously read column in sequential mode.
- There was an asynchronous operation in progress. This applies to all Get* methods when running in sequential mode, as they could be called while reading a stream.
-
- is specified in the connection string.
+ There was an asynchronous operation in progress. This applies to all Get* methods when running in sequential mode, as they could be called while reading a stream.
+
Trying to read a column that does not exist.
@@ -1133,13 +1130,11 @@
- Calling more than once for the same instance before task completion.
-
- is specified in the connection string.
+ Calling more than once for the same instance before task completion.SQL Server returned an error while executing the command text.
@@ -1177,13 +1172,11 @@
## Remarks
If the `behavior` parameter of is set to `Default`, reads the entire row before returning the Task.
- For more information, including code samples, about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/dotnet/framework/data/adonet/asynchronous-programming).
+ For more information, including code samples, about asynchronous programming in the .NET Framework Data Provider for SQL Server, see [Asynchronous Programming](/sql/connect/ado-net/asynchronous-programming).
]]>
- Calling more than once for the same instance before task completion.
-
- is specified in the connection string.
+ Calling more than once for the same instance before task completion.SQL Server returned an error while executing the command text.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlDependency.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlDependency.xml
index d4ecfc52c0..379fb5c930 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlDependency.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlDependency.xml
@@ -14,7 +14,7 @@
> [!NOTE]
> was designed to be used in ASP.NET or middle-tier services where there is a relatively small number of servers having dependencies active against the database. It was not designed for use in client applications, where hundreds or thousands of client computers would have objects set up for a single database server. If you are developing an application where you need reliable sub-second notifications when data changes, review the sections [Planning an Efficient Query Notifications Strategy](https://docs.microsoft.com/previous-versions/sql/sql-server-2008-r2/ms187528(v=sql.105)#planning-an-efficient-query-notifications-strategy) and [Alternatives to Query Notifications](https://docs.microsoft.com/previous-versions/sql/sql-server-2008-r2/ms187528(v=sql.105)#alternatives-to-query-notifications) in the [Planning for Notifications](https://docs.microsoft.com/previous-versions/sql/sql-server-2008-r2/ms187528(v%3dsql.105)) article.
- For more information, see [Query Notifications in SQL Server](/dotnet/framework/data/adonet/sql/query-notifications-in-sql-server) and [Building Notification Solutions](https://docs.microsoft.com/previous-versions/sql/sql-server-2005/ms171065(v%3dsql.90)).
+ For more information, see [Query Notifications in SQL Server](/sql/connect/ado-net/sql/query-notifications-sql-server) and [Building Notification Solutions](https://docs.microsoft.com/previous-versions/sql/sql-server-2005/ms171065(v%3dsql.90)).
> [!NOTE]
> The event may be generated on a different thread from the thread that initiated command execution.
@@ -206,7 +206,7 @@
- Stops a listener for a connection specified in a previous call.
+ Stops a listener for a connection specified in a previous call.
Connection string for the instance of SQL Server that was used in a previous call.
- Stops a listener for a connection specified in a previous call.
+ Stops a listener for a connection specified in a previous call. if the listener was completely stopped; if the was unbound from the listener, but there are is at least one other using the same listener.
@@ -237,7 +237,7 @@
Connection string for the instance of SQL Server that was used in a previous call.
The SQL Server Service Broker queue that was used in a previous call.
- Stops a listener for a connection specified in a previous call.
+ Stops a listener for a connection specified in a previous call. if the listener was completely stopped; if the was unbound from the listener, but there is at least one other using the same listener.
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlException.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlException.xml
index c5eafa53b1..9bb1ef18f3 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlException.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlException.xml
@@ -105,7 +105,7 @@ catch (Exception ex) {
- Represents the client connection ID. For more information, see Data Tracing in ADO.NET.
+ Represents the client connection ID. For more information, see Data Tracing in ADO.NET.The client connection ID.
- Represents a parameter to a and optionally its mapping to columns. This class cannot be inherited. For more information on parameters, see [Configuring Parameters and Parameter Data Types](/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types).
+ Represents a parameter to a and optionally its mapping to columns. This class cannot be inherited. For more information on parameters, see [Configuring parameters](/sql/connect/ado-net/configure-parameters). [!NOTE]
> Nameless, also called ordinal, parameters are not supported by the .NET Framework Data Provider for SQL Server.
- For more information, along with additional sample code demonstrating how to use parameters, see [Commands and Parameters](/dotnet/framework/data/adonet/commands-and-parameters).
+ For more information, along with additional sample code demonstrating how to use parameters, see [Commands and Parameters](/sql/connect/ado-net/commands-parameters).
## Examples
- The following example creates multiple instances of through the collection within the . These parameters are used to select data from the data source and put the data in the . This example assumes that a and a have already been created by using the appropriate schema, commands, and connection. For more information and additional examples on using parameters, see [Retrieving and Modifying Data in ADO.NET](/dotnet/framework/data/adonet/retrieving-and-modifying-data) and [Configuring Parameters and Parameter Data Types](/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types).
+ The following example creates multiple instances of through the collection within the . These parameters are used to select data from the data source and put the data in the . This example assumes that a and a have already been created by using the appropriate schema, commands, and connection. For more information and additional examples on using parameters, see [Retrieving and Modifying Data in ADO.NET](/sql/connect/ado-net/retrieving-modifying-data) and [Configuring parameters](/sql/connect/ado-net/configure-parameters).
[!code-csharp[SqlParameterCollection_Add6](~/../sqlclient/doc/samples/SqlParameterCollection_Add6.cs#1)]
@@ -203,7 +203,7 @@ If you do not perform this conversion, the compiler assumes that you are trying
## Remarks
The and are linked. Therefore, setting the changes the to a supporting .
- For a list of the supported data types, see the appropriate member. For more information, see [DataAdapter Parameters](/dotnet/framework/data/adonet/dataadapter-parameters).
+ For a list of the supported data types, see the appropriate member. For more information, see [DataAdapter Parameters](/sql/connect/ado-net/dataadapter-parameters).
@@ -231,11 +231,11 @@ If you do not perform this conversion, the compiler assumes that you are trying
## Examples
The following example creates a and sets some of its properties.
- [Commands and Parameters](/dotnet/framework/data/adonet/commands-and-parameters)
+ [Commands and Parameters](/sql/connect/ado-net/commands-parameters)
- [DataAdapter Parameters](/dotnet/framework/data/adonet/dataadapter-parameters)
+ [DataAdapter Parameters](/sql/connect/ado-net/dataadapter-parameters)
- [SQL Server and ADO.NET](/dotnet/framework/data/adonet/sql/)
+ [SQL Server and ADO.NET](/sql/connect/ado-net/sql/)
]]>
@@ -428,7 +428,7 @@ static void CreateSqlParameterLocaleId(){
For fixed length data types, the value of is ignored. It can be retrieved for informational purposes, and returns the maximum amount of bytes the provider uses when transmitting the value of the parameter to the server.
- For information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
@@ -449,7 +449,7 @@ static void CreateSqlParameterLocaleId(){
## Remarks
When is set to anything other than an empty string, the value of the parameter is retrieved from the column with the name. If is set to `Input`, the value is taken from the . If is set to `Output`, the value is taken from the data source. A of `InputOutput` is a combination of both.
- For more information about how to use the property, see [DataAdapter Parameters](/dotnet/framework/data/adonet/dataadapter-parameters) and [Updating Data Sources with DataAdapters](/dotnet/framework/data/adonet/updating-data-sources-with-dataadapters).
+ For more information about how to use the property, see [DataAdapter Parameters](/sql/connect/ado-net/dataadapter-parameters) and [Updating Data Sources with DataAdapters](/sql/connect/ado-net/update-data-sources-with-dataadapters).
@@ -517,9 +517,9 @@ FieldName = @OriginalFieldName
## Remarks
The and are linked. Therefore, setting the changes the to a supporting .
- For a list of the supported data types, see the appropriate member. For more information, see [DataAdapter Parameters](/dotnet/framework/data/adonet/dataadapter-parameters).
+ For a list of the supported data types, see the appropriate member. For more information, see [DataAdapter Parameters](/sql/connect/ado-net/dataadapter-parameters).
- For information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
]]>
@@ -543,7 +543,7 @@ FieldName = @OriginalFieldName
Use the property to return parameter values as common language runtime (CLR) types.
- For information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
]]>
@@ -601,7 +601,7 @@ FieldName = @OriginalFieldName
The property is overwritten by `SqlDataAdapter.UpdateCommand`.
- For information about streaming, see [SqlClient Streaming Support](/dotnet/framework/data/adonet/sqlclient-streaming-support).
+ For information about streaming, see [SqlClient Streaming Support](/sql/connect/ado-net/sqlclient-streaming-support).
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlParameterCollection.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlParameterCollection.xml
index 1141a8ec68..c75791c6bc 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlParameterCollection.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlParameterCollection.xml
@@ -9,7 +9,7 @@
## Remarks
If the command contains an ad hoc SQL statement, as opposed to a stored-procedure name, the number of the parameters in the collection must be equal to the number of parameter placeholders within the command text, or SQL Server raises an error. With a stored procedure, all the parameters declared in the stored procedure without a default value must be provided. Parameters declared with a default value are optional. This lets you specify a value other than the default.
-For more information with additional sample code demonstrating how to use parameters, see [Commands and Parameters](/dotnet/framework/data/adonet/commands-and-parameters).
+For more information with additional sample code demonstrating how to use parameters, see [Commands and Parameters](/sql/connect/ado-net/commands-parameters).
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlRetryIntervalBaseEnumerator.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryIntervalBaseEnumerator.xml
new file mode 100644
index 0000000000..8856f2fe22
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryIntervalBaseEnumerator.xml
@@ -0,0 +1,55 @@
+
+
+
+
+ Generates a sequence of time intervals.
+
+
+ Initializes a new instance of the class with a default value of zero for the gap time, minimum, and maximum interval time.
+
+
+ The gap time used to calculate the time delay before each attempt.
+ The maximum time allowed as a gap time.
+ The minimum time allowed as a gap time.
+ Initializes a new instance of the class.
+ The supplied arguments failed validation.
+
+
+ The default gap time of each interval.
+
+
+ The minimum allowed time interval value.
+
+
+ The maximum allowed time interval value.
+
+
+ Gets the element in the collection at the current position of the enumerator.
+
+
+ Sets the enumerator to its initial position, which is before the first element in the collection.
+
+
+ The gap time of each interval. Must be between 0 and 120 seconds.
+ Maximum time interval value. Must be between 0 and 120 seconds.
+ Minimum time interval value. Must be less than maximum time interval and between 0 and 120 seconds.
+ Validate the enumeration parameters.
+ The supplied arguments failed validation.
+
+
+ Calculates the next interval time.
+ Returns the next gap time interval.
+
+
+ Advances the enumerator to the next element of the collection.
+ Returns , if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection.
+
+
+ Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+
+
+ Creates a new object that is a copy of the current instance.
+ A new object that is a copy of this instance.
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicBase.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicBase.xml
new file mode 100644
index 0000000000..3766fa205e
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicBase.xml
@@ -0,0 +1,57 @@
+
+
+
+
+ Retrieves the next time interval with respect to the number of retries if a transient condition occurs.
+
+
+ Maximum number of retries.
+
+ that returns the maximum number of retry execution attempts that will be attempted after the first failure.
+
+
+ Current retry number starting from zero.
+
+ that returns the number of retry execution attempts after the first failure.
+
+
+ The timer interval enumerator.
+
+ value that indicates an enumerator to generate a sequence of time intervals.
+
+
+ Delegate to a transient condition predicate. The function that this delegate points to must return a true value when an expected transient exception happens.
+
+ value that delegates to a function that receives a input parameter.
+
+
+ The sender object.
+ Pre-retry validation for the sender state.
+ Returns if the sender is authorized to retry the operation.
+
+ [IMPORTANT!]
+> Operations that are part of a **Transaction** are not safe to retry without specific knowledge of business logic. Due to this complexity, retry logic should be managed at the application level.
+
+> [!NOTE]
+> The `RetryCondition` is an extra condition that checks before executing the `TransientPredicate` and the default condition always returns **true**.
+
+]]>
+
+
+
+ The interval time that is generated by the `RetryIntervalEnumerator`.
+ Try to get the next interval time by using the enumerator if the counter does not exceed the number of retries.
+ Returns if the number of retry attempts has not been exceeded; otherwise .
+
+
+ Set the counters and enumerator to default values for next use.
+
+
+ Creates a new object that is a copy of the current instance.
+ When implemented in a derived class, the method is expected to return a new object of the current instance. The default implementation throws NotImplementedException.
+ In all cases.
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicBaseProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicBaseProvider.xml
new file mode 100644
index 0000000000..031c2b1ff7
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicBaseProvider.xml
@@ -0,0 +1,90 @@
+
+
+
+
+ Applies retry logic on an operation through the `Execute` or `ExecuteAsync` function.
+
+
+ Occurs before applying the calculated delay time and executing the function on a next attempt.
+
+ with event argument of object can be subscribed.
+
+ [IMPORTANT!]
+> Don't block execution with a time consuming action when an event occurs. For instance, if you log data to a file, run it in a new thread to avoid blocking the main execution thread.
+
+]]>
+
+
+
+
+ Defines the retry logic used to decide when to retry based on the encountered exception.
+
+ [!NOTE]
+> The `RetryLogic` property is assigned at `SqlRetryLogicBaseProvider` creation and its value is used as a template internally. Don't use it to monitor the status of the retry logic during and after execution. Instead, use the event to collect data about retry executions.
+
+]]>
+
+
+
+
+ The object that the `function` returns when executed.
+ The source of the event.
+ The operation to re-execute if a transient condition occurs.
+ Executes a function and applies retry logic, if enabled. **Note:** Exceptions will be reported via an aggregate exception if the execution isn't successful via retry attempts.
+
+ The return value of the `function` if it runs without exception.
+
+ [!NOTE]
+> The type of exception depends on the `function`'s internal implementation. But if the exception is due to all retry attempts failing, it will be an that consists of all exceptions that happened during the failed attempts.
+
+]]>
+
+
+ The `function` parameter can't be `null`.
+ The collection of exceptions after all retry attempts have failed.
+
+
+ The object that the `function` returns in a Task when executed.
+ The source of the event.
+ The operation to re-execute if a transient condition occurs.
+ The cancellation instruction.
+ Executes a function and applies retry logic, if enabled. The cancellation token can be used to request that the operation be abandoned before the execution attempts are exceeded. **Note:** Exceptions will be reported via the returned Task object, which will contain an aggregate exception if execution fails for all retry attempts.
+ A task representing the asynchronous operation. The results of the task will be the return value of the `function`, if it runs without exception.
+
+ [!NOTE]
+> If the exception comes from all retry attempts failing, it will be an that consists of all exceptions from the failed attempts.
+
+]]>
+
+
+ The `function` parameter can't be `null`.
+ The collection of exceptions after failed retry attempts.
+
+
+ The source of the event.
+ The operation to re-execute if a transient condition occurs.
+ The cancellation instruction.
+ Executes a function and applies retry logic, if enabled. The cancellation token can be used to request that the operation be abandoned before the execution attempts are exceeded. **Note:** Exceptions will be reported via the returned Task object, which will contain an aggregate exception if execution fails for all retry attempts.
+ A Task or an exception.
+
+ [!NOTE]
+> If the exception comes from all retry attempts failing, it will be an that consists of all exceptions from the failed attempts.
+
+]]>
+
+
+ The `function` parameter can't be `null`.
+ The collection of exceptions after failed retry attempts.
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicOption.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicOption.xml
new file mode 100644
index 0000000000..8ba200753b
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryLogicOption.xml
@@ -0,0 +1,47 @@
+
+
+
+
+ Provides the retry logic parameters to create an instance of the class by using methods.
+
+
+ object that is configured to apply retry logic for the error number **102** for a maximum of **5** times and **3** to **60** seconds gap time between each run. It will only work for the `Select` SQL statements assigned to the .
+
+[!code-csharp[SqlConfigurableRetryLogic_SqlRetryLogicOptions#1](~/../sqlclient/doc/samples/SqlConfigurableRetryLogic_SqlRetryLogicOptions.cs#1)]
+
+]]>
+
+
+ Sets the number of times to try and execute the function.
+
+ between 1 and 60; 1 means to execute one time and if an error is encountered, don't retry.
+
+
+ Sets the gap time interval as a object.
+
+ The upcoming gap time before the next execution attempt; must be between 0 and 120 seconds.
+
+
+ Sets the minimum allowed gap time interval as a object.
+
+ The minimum upcoming gap time before the next execution attempt; the default value is **zero** and must be between 0 and 120 seconds.
+
+
+ Sets the allowed maximum gap time interval as a object.
+
+ The maximum upcoming gap time interval before the next execution attempt; must be between 0 and 120 seconds.
+
+
+ Sets the list of transient error numbers on which to retry when they occur.
+ List of ; Set to to use the internal list of exceptions from the object.
+
+
+ Sets a pre-retry validation function on the to only include specific SQL statements.
+
+ The pre-retry validation delegate function; if the `CommandText` is authorized to retry the operation.
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlRetryingEventArgs.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryingEventArgs.xml
new file mode 100644
index 0000000000..f7911a4160
--- /dev/null
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlRetryingEventArgs.xml
@@ -0,0 +1,32 @@
+
+
+
+
+ Represents the set of arguments passed to the event.
+
+
+ The current retry attempt count.
+ The delay that indicates how long the current thread will be suspended before the next iteration is invoked.
+ The list of exceptions since the first retry that caused the retry logic to re-execute the function.
+ Initializes a new instance of the class.
+
+
+ Retry-attempt-number, after the first exception occurrence.
+
+ that returns the number of retry execution attempts; starting from 1.
+
+
+ Gets or sets a value that indicates whether the retry logic should be canceled.
+ If set to , the execution attempt will be interrupted immediately.
+
+
+ Gets the current waiting time as a object.
+
+ The upcoming gap time before the next execution attempt.
+
+
+ Gets the list of exceptions since the first attempt failure.
+ List of occurred exceptions.
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlTypes/SqlFileStream.xml b/doc/snippets/Microsoft.Data.SqlTypes/SqlFileStream.xml
index 1330327723..2397ba11a3 100644
--- a/doc/snippets/Microsoft.Data.SqlTypes/SqlFileStream.xml
+++ b/doc/snippets/Microsoft.Data.SqlTypes/SqlFileStream.xml
@@ -15,7 +15,7 @@ Specifying the FILESTREAM attribute on a `varbinary(max)` column causes SQL Serv
The class is derived from the class, which represents an abstraction of a sequence of bytes from some arbitrary data source such as a file or a block of memory. You can read from a FILESTREAM by transferring data from a stream into a data structure such as an array of bytes. You can write to a FILESTREAM by transferring the data from a data structure into a stream. You can also seek within the stream, which allows you to query and modify data at the current position within the stream.
-For conceptual documentation and code examples, see [FILESTREAM Data](/dotnet/framework/data/adonet/sql/filestream-data).
+For conceptual documentation and code examples, see [FILESTREAM Data](/sql/connect/ado-net/sql/filestream-data).
For documentation about setting up and configuring FILESTREAM data on SQL Server, see [Designing and Implementing FILESTREAM Storage](https://go.microsoft.com/fwlink/?LinkId=121499) in SQL Server 2008 Books Online.
diff --git a/doc/snippets/Microsoft.SqlServer.Server/DataAccessKind.xml b/doc/snippets/Microsoft.SqlServer.Server/DataAccessKind.xml
new file mode 100644
index 0000000000..1590300ea4
--- /dev/null
+++ b/doc/snippets/Microsoft.SqlServer.Server/DataAccessKind.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ Describes the type of access to user data for a user-defined method or function.
+
+ and to indicate whether the method or function uses ADO.NET to connect back to the database using the "context connection."
+
+Note that methods and functions are not allowed to make changes to the database, so the options for this enumeration are `None` (meaning no data-access performed by the method or function) and `Read` (meaning that the method or function perform read-only data-access operations, such as executing SELECT statements).
+
+ ]]>
+
+
+
+ The method or function does not access user data.
+
+
+ The method or function reads user data.
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/Format.xml b/doc/snippets/Microsoft.SqlServer.Server/Format.xml
similarity index 67%
rename from doc/snippets/Microsoft.Data.SqlClient.Server/Format.xml
rename to doc/snippets/Microsoft.SqlServer.Server/Format.xml
index b15cd6eadb..31b5776207 100644
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/Format.xml
+++ b/doc/snippets/Microsoft.SqlServer.Server/Format.xml
@@ -2,39 +2,44 @@
- Used by and to indicate the serialization format of a user-defined type (UDT) or aggregate.
+ Used by and to indicate the serialization format of a user-defined type (UDT) or aggregate. and to indicate the serialization format of a user-defined type (UDT) or aggregate. Use of the `Native` and `UserDefined` enumeration members has special requirements.
+
+## Remarks
+
+This enumeration is used by and to indicate the serialization format of a user-defined type (UDT) or aggregate. Use of the `Native` and `UserDefined` enumeration members has special requirements.
+
- `Format.Native`
The requirements for the `Format.Native` format are:
-
+
- The with a property value of must be applied to the aggregate or UDT if it is defined in a class and not a structure. This controls the physical layout of the data fields and is used to force the members to be laid out sequentially in the order they appear. SQL Server uses this attribute to determine the field order for UDTs with multiple fields.
-
+
- The type must contain at least one member (serialized values cannot be zero bytes in size).
-
+
- All the fields of the aggregate must be *blittable*; that is, they must have a common representation in both managed and unmanaged memory and not require special handling by the interop marshaler.
-
+
- All the fields of the UDT should be of one of the following types that can be serialized: `bool`, `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `float`, `double`, , , , , , , , , or other value types defined by the user that contain fields of one of these types.
- The aggregate must not specify a value for `MaxByteSize`.
-
+
- The aggregate must not have any [NonSerialized] fields.
-
+
- Fields must not be marked as an explicit layout (with a of ).
- `Format.UserDefined`
The requirements for the `Format.UserDefined` format are:
- The aggregate must specify a value for `MaxByteSize`.
-
- - Specify the attribute property. The default value is `false`.
-
- - If you omit any field in the or methods, the state of that field is not serialized.
+
+ - Specify the attribute property. The default value is `false`.
+
+ - If you omit any field in the or methods, the state of that field is not serialized.
+
## Examples
+
The following example shows the `UserDefinedType` attribute of the Point UDT. The UDT is byte-ordered, is named "Point", has a validation method named "ValidatePoint", and uses the native serialization format.
-
-[!code-csharp[SqlUserDefinedType Example#1](~/../sqlclient/doc/samples/SqlUserDefinedType.cs#1)]
-
+
+[!code-csharp[SqlUserDefinedTypeAttribute Example#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedTypeAttribute_Sample.cs#1)]
+[!code-vb[SqlUserDefinedTypeAttribute Example#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedTypeAttribute_Sample.vb#1)]
+
]]>
@@ -45,7 +50,7 @@ The following example shows the `UserDefinedType` attribute of the Point UDT. T
The serialization format is unknown.
- This serialization format gives the developer full control over the binary format through the and methods.
+ This serialization format gives the developer full control over the binary format through the and methods.
diff --git a/doc/snippets/Microsoft.SqlServer.Server/IBinarySerialize.xml b/doc/snippets/Microsoft.SqlServer.Server/IBinarySerialize.xml
new file mode 100644
index 0000000000..79128e5655
--- /dev/null
+++ b/doc/snippets/Microsoft.SqlServer.Server/IBinarySerialize.xml
@@ -0,0 +1,56 @@
+
+
+
+
+ Provides custom implementation for user-defined type (UDT) and user-defined aggregate serialization and deserialization.
+
+ .`Native` or .`UserDefined`.
+
+.`Native` allows SQL Server to handle serialization and deserialization automatically, but the format has restrictions on the kind of types it can handle. .`UserDefined` allows user-defined types and aggregates to handle their own serialization. User-defined types and aggregates must be marked with .`UserDefined` in the `SqlUserDefinedType` or `SqlUserDefinedAggregate` attribute, and must implement the interface.
+
+Note that even with custom serialization, the total size of each instance must be under the maximum allowed limit, currently 8000 bytes.
+
+ ]]>
+
+
+
+ The stream from which the object is deserialized.
+ Generates a user-defined type (UDT) or user-defined aggregate from its binary form.
+
+ method must reconstitute your object using the information written by the method.
+
+## Examples
+The following example shows the implementation of the method of a UDT, which uses a to de-serialize a previously persisted UDT. This example assumes that the UDT has two data properties: `StringValue` and `DoubleValue`.
+
+[!code-csharp[IBinarySerialize Samples#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_IBinarySerialize_Sample.cs#1)]
+[!code-vb[IBinarySerialize Samples#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_IBinarySerialize_Sample.vb#1)]
+
+ ]]>
+
+
+
+ The stream to which the UDT or user-defined aggregate is serialized.
+ Converts a user-defined type (UDT) or user-defined aggregate into its binary format so that it may be persisted.
+
+ method to reconstitute your UDT or user-defined aggregate.
+
+## Examples
+The following example shows the implementation of the method of a UDT, which uses a to serialize the UDT in the user-defined binary format. The purpose of the null character padding is to ensure that the string value is completely separated from the double value, so that one UDT is compared to another in Transact-SQL code, string bytes are compared to string bytes and double bytes are compared to double bytes.
+
+[!code-csharp[IBinarySerialize Samples#2](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_IBinarySerialize_Sample.cs#2)]
+[!code-vb[IBinarySerialize Samples#2](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_IBinarySerialize_Sample.vb#2)]
+
+ ]]>
+
+
+
+
diff --git a/doc/snippets/Microsoft.SqlServer.Server/InvalidUdtException.xml b/doc/snippets/Microsoft.SqlServer.Server/InvalidUdtException.xml
new file mode 100644
index 0000000000..9ec4002c76
--- /dev/null
+++ b/doc/snippets/Microsoft.SqlServer.Server/InvalidUdtException.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ Thrown when SQL Server or the ADO.NET provider detects an invalid user-defined type (UDT).
+ To be added.
+
+
+ The object.
+ The object.
+ Streams all the properties into the class for the given .
+
+ class to make the class serializable.
+
+ ]]>
+
+
+
+ The object.
+ The object that represents a string in string resources. The default value is `SqlUdtReason_NoUdtAttribute` which looks up a localized string similar to "no UDT attribute".
+ Creates a new object.
+ A new object.
+
+ [!IMPORTANT]
+> This function is exposed for backward compatibility and should be used with the default value for the `resourceReason` parameter.
+
+ ]]>
+
+
+
+
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlFacetAttribute.xml b/doc/snippets/Microsoft.SqlServer.Server/SqlFacetAttribute.xml
similarity index 56%
rename from doc/snippets/Microsoft.Data.SqlClient.Server/SqlFacetAttribute.xml
rename to doc/snippets/Microsoft.SqlServer.Server/SqlFacetAttribute.xml
index bbe76cdd22..cae95f8032 100644
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlFacetAttribute.xml
+++ b/doc/snippets/Microsoft.SqlServer.Server/SqlFacetAttribute.xml
@@ -7,14 +7,14 @@
may only be specified on non-void return values.
-
- is used only to derive information about the return type, and is not intended to be a constraint specification on what can be stored in the type. Thus, if a field has a indicating its size to be 2 characters, then the SQL Server type of the field access expression is of size 2, but assignments into the field are not restricted by this facet.
-
- The table below captures the matrix of valid values for the various properties for specific field types. In this table, "Y" indicates that the property is valid, and "N" indicates that the property is not valid.
-
- The specified must be compatible with the field type. If the property is not valid, type registration will report an error if the user specifies a non-default value for the property. The maximum values for and properties are 38. For the property, the value should be in the range of 1-8000 for binary and non-Unicode data, 1-4000 for Unicode data, or -1. All other values are not valid.
-
+ may only be specified on non-void return values.
+
+ is used only to derive information about the return type, and is not intended to be a constraint specification on what can be stored in the type. Thus, if a field has a indicating its size to be 2 characters, then the SQL Server type of the field access expression is of size 2, but assignments into the field are not restricted by this facet.
+
+The table below captures the matrix of valid values for the various properties for specific field types. In this table, "Y" indicates that the property is valid, and "N" indicates that the property is not valid.
+
+The specified must be compatible with the field type. If the property is not valid, type registration will report an error if the user specifies a non-default value for the property. The maximum values for and properties are 38. For the property, the value should be in the range of 1-8000 for binary and non-Unicode data, 1-4000 for Unicode data, or -1. All other values are not valid.
+
|Type|IsFixedLength|MaxSize|Precision|Scale|IsNullable|
|----------|-------------------|-------------|---------------|-----------|----------------|
||N|N|N|N|Y|
@@ -39,9 +39,9 @@
|Char[]|Y|Y|N|N|Y|
||N|N|N|Y1|N|
||N|N|Y|Y|Y|
-
- (1) Specifying the scale on a DateTime type will cause the value to be returned to Transact-SQL as a DateTime2 type with the specified scale.
-
+
+(1) Specifying the scale on a DateTime type will cause the value to be returned to Transact-SQL as a DateTime2 type with the specified scale.
+
]]>
@@ -56,7 +56,7 @@
property is set to 1.
+This property must be set to `false` if the property is set to 1.
The default value is `false`.
@@ -71,8 +71,8 @@ The default value is `false`.
@@ -83,12 +83,12 @@ The default value is `false`.
@@ -99,10 +99,10 @@ The default value is `false`.
property is valid only for numeric types. The property must also be specified when setting the property.
-
- The maximum value of the property is 38; the default value is 38.
-
+The property is valid only for numeric types. The property must also be specified when setting the property.
+
+The maximum value of the property is 38; the default value is 38.
+
]]>
@@ -113,10 +113,10 @@ The default value is `false`.
property is valid only for decimal types. The property must also be specified when setting the property.
-
- The maximum value of the property is 38; the default value is 0.
-
+The property is valid only for decimal types. The property must also be specified when setting the property.
+
+The maximum value of the property is 38; the default value is 0.
+
]]>
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlFunctionAttribute.xml b/doc/snippets/Microsoft.SqlServer.Server/SqlFunctionAttribute.xml
similarity index 62%
rename from doc/snippets/Microsoft.Data.SqlClient.Server/SqlFunctionAttribute.xml
rename to doc/snippets/Microsoft.SqlServer.Server/SqlFunctionAttribute.xml
index 7221363628..ddf4c76e4b 100644
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlFunctionAttribute.xml
+++ b/doc/snippets/Microsoft.SqlServer.Server/SqlFunctionAttribute.xml
@@ -9,26 +9,27 @@
## Examples
The following example shows an aggregate function that returns a list of files in the specified directory path.
-[!code-csharp[SqlFunctionAttribute Sample#1](~/../sqlclient/doc/samples/SqlFunctionAttribute.cs#1)]
+[!code-csharp[SqlFunctionAttribute Sample#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlFunctionAttribute_Sample.cs#1)]
+[!code-vb[SqlFunctionAttribute Sample#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlFunctionAttribute_Sample.vb#1)]
]]>
- An optional attribute on a user-defined aggregate, used to indicate that the method should be registered in SQL Server as a function. Also used to set the , , , , , , and properties of the function attribute.
+ An optional attribute on a user-defined aggregate, used to indicate that the method should be registered in SQL Server as a function. Also used to set the , , , , , , and properties of the function attribute.To be added.Indicates whether the function involves access to user data stored in the local instance of SQL Server.
- .: Does not access data. .: Only reads user data.
+ .: Does not access data. .: Only reads user data.
. is also required when connecting to remote servers if transactions integration is required (the default).
+The default is . is also required when connecting to remote servers if transactions integration is required (the default).
-If a Transact-SQL query is executed from inside a table-valued function (TVF), the property should be set.
+If a Transact-SQL query is executed from inside a table-valued function (TVF), the property should be set.
]]>
@@ -47,11 +48,11 @@ If a Transact-SQL query is executed from inside a table-valued function (TVF), t
## Remarks
A user-defined function is said to be deterministic if it always produces the same output values given the same input values and the same database state.
-The property is also useful for indexing the result of the function in the form of indexed computed columns and indexed views. If this property is not specified, the function is assumed to be non-deterministic.
+The property is also useful for indexing the result of the function in the form of indexed computed columns and indexed views. If this property is not specified, the function is assumed to be non-deterministic.
-Functions that access local data can be deterministic. The data access characteristic is captured separately by the and properties.
+Functions that access local data can be deterministic. The data access characteristic is captured separately by the and properties.
-Note that data access to remote servers (for example, using a to connect to another SQL Server instance) is available in user-defined functions. However, you must still honor the declaration. If the common language runtime (CLR) function is marked as deterministic, it should not cause side-effects in the remote server. While side-effects against the context connection are restricted, SQL Server will not enforce the restriction for side-effects over remote connections.
+Note that data access to remote servers (for example, using a to connect to another SQL Server instance) is available in user-defined functions. However, you must still honor the declaration. If the common language runtime (CLR) function is marked as deterministic, it should not cause side-effects in the remote server. While side-effects against the context connection are restricted, SQL Server will not enforce the restriction for side-effects over remote connections.
The default value of this attribute is `false`.
@@ -84,22 +85,24 @@ The default value of this attribute is `false`.
## Remarks
This attribute is used only by Microsoft Visual Studio to automatically register the specified method as a user-defined function. It is not used by SQL Server.
-Thee following example specifies that the user-defined function is referenced using the name `sp_scalarFunc`.
+The following example specifies that the user-defined function is referenced using the name `sp_scalarFunc`.
## Examples
-[!code-csharp[SqlFunction#10](~/../sqlclient/doc/samples/SqlFunction.cs#10)]
+[!code-csharp[SqlFunctionAttribute Samples#10](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/SqlFunctionAttribute_SqlFunction.cs#10)]
+[!code-vb[SqlFunctionAttribute Samples#10](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlFunctionAttribute_SqlFunction.vb#10)]
+
]]>
Indicates whether the function requires access to data stored in the system catalogs or virtual system tables of SQL Server.
- .: Does not access system data. .: Only reads system data.
+ .: Does not access system data. .: Only reads system data.
.
+The default is .
]]>
@@ -116,7 +119,9 @@ This attribute is used only by Microsoft Visual Studio to automatically register
The following example specifies that the user-defined function is referenced using the name `sp_tableFunc`. The `TableDefinition` property has the value `letter nchar(1)`.
## Examples
-[!code-csharp[SqlFunction#11](~/../sqlclient/doc/samples/SqlFunction.cs#11)]
+
+[!code-csharp[SqlFunctionAttribute Samples#11](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/SqlFunctionAttribute_SqlFunction.cs#11)]
+[!code-vb[SqlFunctionAttribute Samples#11](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/SqlFunctionAttribute_SqlFunction.vb#11)]
]]>
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlMethodAttribute.xml b/doc/snippets/Microsoft.SqlServer.Server/SqlMethodAttribute.xml
similarity index 63%
rename from doc/snippets/Microsoft.Data.SqlClient.Server/SqlMethodAttribute.xml
rename to doc/snippets/Microsoft.SqlServer.Server/SqlMethodAttribute.xml
index 95f73cda49..55a9858ded 100644
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlMethodAttribute.xml
+++ b/doc/snippets/Microsoft.SqlServer.Server/SqlMethodAttribute.xml
@@ -7,14 +7,14 @@
should be used on the setter or the getter directly.
+For a property, the should be used on the setter or the getter directly.
- inherits from a , so inherits the `FillRowMethodName` and `TableDefinition` fields from . Note that it is not possible to write a table-valued method, although the names of these fields might suggest that it is possible.
+ inherits from a , so inherits the `FillRowMethodName` and `TableDefinition` fields from . Note that it is not possible to write a table-valued method, although the names of these fields might suggest that it is possible.
## Examples
The following example shows a UDT method that is attributed to indicate that the method will not be invoked on null instances of the type, that the method will not change the state of the type, and that the method will not be called when `null` parameters are supplied to the method invocation.
-[!code-csharp[SqlMethod Sample#1](~/../sqlclient/doc/samples/SqlMethod.cs#1)]
+[!code-csharp[SqlMethodAttribute Samples#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/SqlMethod.cs#1)]
]]>
@@ -43,11 +43,11 @@ The default value of the `InvokeIfReceiverIsNull` property is `false`. That is,
property is set to `true` and the return type of the method is `void`, SQL Server marks the method as a mutator. A mutator method is one that causes a state change in the UDT instance. Mutator methods can be called in assignment statements or data modification statements, but cannot be used in queries. If a method is marked as a mutator but does not return void, then CREATE TYPE does not fail with an error. Even though a returned value other than `void` does not raise an error, the returned value is not accessible and cannot be used.
+If the property is set to `true` and the return type of the method is `void`, SQL Server marks the method as a mutator. A mutator method is one that causes a state change in the UDT instance. Mutator methods can be called in assignment statements or data modification statements, but cannot be used in queries. If a method is marked as a mutator but does not return void, then CREATE TYPE does not fail with an error. Even though a returned value other than `void` does not raise an error, the returned value is not accessible and cannot be used.
-The default value of the property is `false`.
+The default value of the property is `false`.
-A property can be a mutator if is used on the setter and is set to `true`. However, a property setter is implicitly treated as a mutator, so it is not necessary to set the property of the to `true`.
+A property can be a mutator if is used on the setter and is set to `true`. However, a property setter is implicitly treated as a mutator, so it is not necessary to set the property of the to `true`.
]]>
@@ -59,7 +59,7 @@ A property can be a mutator if property is `true`.
+The default value of the property is `true`.
]]>
diff --git a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlUserDefinedAggregateAttribute.xml b/doc/snippets/Microsoft.SqlServer.Server/SqlUserDefinedAggregateAttribute.xml
similarity index 70%
rename from doc/snippets/Microsoft.Data.SqlClient.Server/SqlUserDefinedAggregateAttribute.xml
rename to doc/snippets/Microsoft.SqlServer.Server/SqlUserDefinedAggregateAttribute.xml
index 5822bac69d..a0a5eafe1b 100644
--- a/doc/snippets/Microsoft.Data.SqlClient.Server/SqlUserDefinedAggregateAttribute.xml
+++ b/doc/snippets/Microsoft.SqlServer.Server/SqlUserDefinedAggregateAttribute.xml
@@ -7,30 +7,32 @@
custom attribute. Every user-defined aggregate must be annotated with this attribute.
+SQL Server creates a user-defined aggregate that is bound to the class definition that has the custom attribute. Every user-defined aggregate must be annotated with this attribute.
See "CLR User-Defined Aggregates" in SQL Server 2005 Books Online for more information on user-defined aggregates and examples.
## Examples
-The following example shows the attribute for a user-defined aggregate. The aggregate uses custom serialization, has a maximum size of 8000 bytes when serialized, and is invariant to nulls, duplicates, and order.
+The following example shows the attribute for a user-defined aggregate. The aggregate uses custom serialization, has a maximum size of 8000 bytes when serialized, and is invariant to nulls, duplicates, and order.
-[!code-csharp[SqlUserDefinedAggregate Sample#1](~/../sqlclient/doc/samples/SqlUserDefinedAggregate.cs#1)]
+[!code-csharp[SqlUserDefinedAggregateAttribute Samples#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedAggregateAttribute_Sample.cs#1)]
+[!code-vb[SqlUserDefinedAggregateAttribute Samples#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedAggregateAttribute_Sample.vb#1)]
]]>
- One of the values representing the serialization format of the aggregate.
+ One of the values representing the serialization format of the aggregate.
A required attribute on a user-defined aggregate, used to indicate that the given type is a user-defined aggregate and the storage format of the user-defined aggregate.
- The serialization format as a .
- A representing the serialization format.
+ The serialization format as a .
+ A representing the serialization format.
@@ -102,13 +104,13 @@ Incorrectly setting this property can result in incorrect query results. This pr
## Remarks
This property does not have to be specified for Native format serialization.
-You must specify the property with the UserDefined serialization .
+You must specify the property with the UserDefined serialization .
-The maximum allowed value for this property is specified by the field.
+The maximum allowed value for this property is specified by the field.
The maximum size allowed is 2 gigabytes (GB). You can specify a number from 1 to 8000 bytes, or -1 to represent a value larger than 8000 bytes, up to 2 gigabytes.
-For an aggregate with user-defined serialization specified, refers to the total size of the serialized data. Consider an aggregate serializing a string of 10 characters (). When the string is serialized using a , the total size of the serialized string is 22 bytes: 2 bytes per Unicode UTF-16 character, multiplied by the maximum number of characters, plus 2 control bytes of overhead incurred from serializing a binary stream. So, when determining the value of , the total size of the serialized data must be considered: the size of the data serialized in binary form plus the overhead incurred by serialization.
+For an aggregate with user-defined serialization specified, refers to the total size of the serialized data. Consider an aggregate serializing a string of 10 characters (). When the string is serialized using a , the total size of the serialized string is 22 bytes: 2 bytes per Unicode UTF-16 character, multiplied by the maximum number of characters, plus 2 control bytes of overhead incurred from serializing a binary stream. So, when determining the value of , the total size of the serialized data must be considered: the size of the data serialized in binary form plus the overhead incurred by serialization.
]]>
diff --git a/doc/snippets/Microsoft.SqlServer.Server/SqlUserDefinedTypeAttribute.xml b/doc/snippets/Microsoft.SqlServer.Server/SqlUserDefinedTypeAttribute.xml
new file mode 100644
index 0000000000..ffd70496cc
--- /dev/null
+++ b/doc/snippets/Microsoft.SqlServer.Server/SqlUserDefinedTypeAttribute.xml
@@ -0,0 +1,139 @@
+
+
+
+
+ Used to mark a type definition in an assembly as a user-defined type (UDT) in SQL Server. The properties on the attribute reflect the physical characteristics used when the type is registered with SQL Server. This class cannot be inherited.
+
+ custom attribute. Every UDT must be annotated with this attribute. See [CLR User-Defined Types](https://go.microsoft.com/fwlink/?LinkId=128028) for more information about UDTs, including an example of a UDT.
+
+## Examples
+The following example shows the `UserDefinedType` attribute of the Point UDT. The UDT is byte-ordered, is named "Point", has a validation method named "ValidatePoint", and uses the native serialization format.
+
+[!code-csharp[SqlUserDefinedTypeAttribute Samples#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/csharp/DataWorks_SqlUserDefinedTypeAttribute_Sample.cs#1)]
+[!code-vb[SqlUserDefinedTypeAttribute Samples#1](~/../sqlclient/doc/samples/Microsoft.SqlServer.Server/visualbasic/DataWorks_SqlUserDefinedTypeAttribute_Sample.vb#1)]
+
+]]>
+
+
+
+ One of the values representing the serialization format of the type.
+ A required attribute on a user-defined type (UDT), used to confirm that the given type is a UDT and to indicate the storage format of the UDT.
+
+
+
+
+
+ The serialization format as a .
+ A value representing the serialization format.
+
+
+ Indicates whether the user-defined type is byte ordered.
+
+ if the user-defined type is byte ordered; otherwise .
+
+ property in effect guarantees that the serialized binary data can be used for semantic ordering of the information. Thus, each instance of a byte-ordered UDT object can only have one serialized representation. When a comparison operation is performed in SQL Server on the serialized bytes, its results should be the same as if the same comparison operation had taken place in managed code.
+
+The following features are supported when is set to `true`:
+
+- The ability to create indexes on columns of this type.
+
+- The ability to create primary and foreign keys as well as CHECK and UNIQUE constraints on columns of this type.
+
+- The ability to use Transact-SQL ORDER BY, GROUP BY, and PARTITION BY clauses. In these cases, the binary representation of the type is used to determine the order.
+
+- The ability to use comparison operators in Transact-SQL statements.
+
+- The ability to persist computed columns of this type.
+
+Note that both the `Native` and `UserDefined` serialization formats support the following comparison operators when is set to `true`:
+
+- Equal to (=)
+
+- Not equal to (!=)
+
+- Greater than (>)
+
+- Less than (\<)
+
+- Greater than or equal to (>=)
+
+- Less than or equal to (<=)
+
+]]>
+
+
+
+ Indicates whether all instances of this user-defined type are the same length.
+
+ if all instances of this type are the same length; otherwise .
+
+
+ . This attribute is only relevant for UDTs with `UserDefined` serialization .
+
+]]>
+
+
+
+ The maximum size of the instance, in bytes.
+ An value representing the maximum size of the instance.
+
+ property with the `UserDefined` serialization .
+
+When connecting to SQL Server 2005 or earlier, must be between 1 and 8000.
+
+When connecting to SQL Server 2008 or later, set between 1 and 8000, for a type whose instances are always 8,000 bytes or less. For types that can have instances larger than 8000, specify -1.
+
+For a UDT with user-defined serialization specified, refers to the total size of the UDT in its serialized form as defined by the user. Consider a UDT with a property of a string of 10 characters (). When the UDT is serialized using a , the total size of the serialized string is 22 bytes: 2 bytes per Unicode UTF-16 character, multiplied by the maximum number of characters, plus 2 control bytes of overhead incurred from serializing a binary stream. So, when determining the value of , the total size of the serialized UDT must be considered: the size of the data serialized in binary form plus the overhead incurred by serialization.
+
+This property should not be used with `Native` serialization .
+
+]]>
+
+
+
+ The SQL Server name of the user-defined type.
+ A value representing the SQL Server name of the user-defined type.
+
+ property is not used within SQL Server, but is used by the Microsoft Visual Studio .NET Integrated Development Environment (IDE).
+
+]]>
+
+
+
+ The name of the method used to validate instances of the user-defined type.
+ A representing the name of the method used to validate instances of the user-defined type.
+
+
+
+
+
+
diff --git a/doc/snippets/Microsoft.SqlServer.Server/SystemDataAccessKind.xml b/doc/snippets/Microsoft.SqlServer.Server/SystemDataAccessKind.xml
new file mode 100644
index 0000000000..93f80783d0
--- /dev/null
+++ b/doc/snippets/Microsoft.SqlServer.Server/SystemDataAccessKind.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ Describes the type of access to system data for a user-defined method or function.
+
+ and to indicate what type of access to system data the method or function has.
+
+Note that methods and functions are not allowed to make changes to the database, so the options for this enumeration are `None` (meaning no data-access performed by the method or function) and `Read` (meaning that the method or function performs read-only data-access operations, such as executing SELECT statements).
+
+ ]]>
+
+
+
+ The method or function does not access system data.
+
+
+ The method or function reads system data.
+
+
+
diff --git a/porting-cheat-sheet.md b/porting-cheat-sheet.md
index e6216863cd..d09c16c77e 100644
--- a/porting-cheat-sheet.md
+++ b/porting-cheat-sheet.md
@@ -4,6 +4,20 @@ This guide is meant to cover all namespace changes needed in client applications
## Namespace Changes needed
+### Microsoft.Data.SqlClient v5.0 and newer
+
+| Namespace Change | Applicability |
+|--|--|
+| `using System.Data.SqlClient;` `using Microsoft.Data.SqlClient;` | Applicable to all classes, enums and delegates. |
+| `using Microsoft.SqlServer.Server;` `using Microsoft.Data.SqlClient.Server;` | Applicable Classes: `SqlDataRecord` `SqlMetaData`
1 _All remaining types continue to be referenced from Microsoft.SqlServer.Server namespace._|
+| `using System.Data.SqlTypes;` `using Microsoft.Data.SqlTypes;` | Applicable Classes: `SqlFileStream`|
+| `using System.Data.Sql;` `using Microsoft.Data.Sql;` | Applicable Classes: `SqlNotificationRequest` |
+| `using System.Data;` `using Microsoft.Data;` | Applicable Classes: `OperationAbortedException`|
+
+1 Breaking change for User-Defined types and Microsoft.SqlServer.Types support over _Microsoft.Data.SqlClient v3.0.0_.
+
+### Microsoft.Data.SqlClient v4.0 and older
+
| Namespace Change | Applicability |
|--|--|
| `using System.Data.SqlClient;` `using Microsoft.Data.SqlClient;` | Applicable to all classes, enums and delegates. |
@@ -12,6 +26,33 @@ This guide is meant to cover all namespace changes needed in client applications
| `using System.Data.Sql;` `using Microsoft.Data.Sql;` | Applicable Classes: `SqlNotificationRequest` |
| `using System.Data;` `using Microsoft.Data;` | Applicable Classes: `OperationAbortedException`|
+## Configuration
+
+For .NET Framework projects it may be necessary to include the following in your App.config or Web.config file:
+
+``` xml
+
+ ...
+
+
+
+
+
+ ...
+
+```
+
+## Functionality Changes
+
+| System.Data.SqlClient | Microsoft.Data.SqlClient |
+|--|--|
+| Can use DateTime object as value for SqlParameter with type `DbType.Time`. | Must use TimeSpan object as value for SqlParameter with type `DbType.Time`. |
+| Using DateTime object as value for SqlParameter with type `DbType.Date` would send date and time to SQL Server. | DateTime object's time components will be truncated when sent to SQL Server using `DbType.Date`. |
+| `Encrypt` defaults to `false`. | Starting in v4.0, default encryption settings were made more secure, requiring opt-in to non-encrypted connections. `Encrypt` defaults to `true` and the driver will always validate the server certificate based on `TrustServerCertificate`. (Previously, server certificates would only be validated if `Encrypt` was also `true`.)
If you need to turn off encryption, you must specify `Encrypt=false`. If you use encryption with a self-signed certificate on the server, you must specify `TrustServerCertificate=true`.
In v5.0, `SqlConnectionStringBuilder.Encrypt` is no longer a `bool`. It's a `SqlConnectionEncryptOption` with multiple values to support `Strict` encryption mode (TDS 8.0). It uses implicit conversion operators to remain code-backwards compatible, but it was a binary breaking change, requiring a recompile of applications. |
+
## Contribute to this Cheat Sheet
We would love the SqlClient community to help enhance this cheat sheet by contributing experiences and challenges faced when porting their applications.
diff --git a/release-notes/1.1/1.1.4.md b/release-notes/1.1/1.1.4.md
new file mode 100644
index 0000000000..a89b6473d0
--- /dev/null
+++ b/release-notes/1.1/1.1.4.md
@@ -0,0 +1,62 @@
+# Release Notes
+
+## General Availability of Microsoft.Data.SqlClient 1.1.4 released 10 March 2021
+
+This update brings the below changes over the previous release:
+
+### Fixed
+- Fixed wrong results issues by changing the timeout timer to ensure a correct execution state [#950](https://github.com/dotnet/SqlClient/pull/950)
+- Fixed MARS header contains errors issue against .NET Framework 4.8+ [#959](https://github.com/dotnet/SqlClient/pull/959)
+
+
+## Target Platform Support
+
+- .NET Framework 4.6+
+- .NET Core 2.1+ (Windows x86, Windows x64, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- System.Data.Common 4.3.0
+- Microsoft.Data.SqlClient.SNI [1.1.0,1.2.0)
+- Microsoft.Identity.Client 3.0.8
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.5.0
+- Microsoft.IdentityModel.JsonWebTokens 5.5.0
+
+#### .NET Core
+
+- Microsoft.Win32.Registry 4.5.0
+- runtime.native.System.Data.SqlClient.sni 4.4.0
+- System.Security.Principal.Windows 4.5.0
+- System.Text.Encoding.CodePages 4.5.0
+- System.Configuration.ConfigurationManager 4.5.0
+- Microsoft.Identity.Client 3.0.8
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.5.0
+- Microsoft.IdentityModel.JsonWebTokens 5.5.0
+
+#### .NET Standard
+
+- Microsoft.Win32.Registry 4.5.0
+- runtime.native.System.Data.SqlClient.sni 4.4.0
+- System.Buffers 4.4.0
+- System.Diagnostics.DiagnosticSource 4.5.0
+- System.Memory 4.5.1
+- System.Security.Principal.Windows 4.5.0
+- System.Text.Encoding.CodePages 4.5.0
+- System.Configuration.ConfigurationManager 4.5.0
+- Microsoft.Identity.Client 3.0.8
+
+### Always Encrypted with secure enclaves
+
+In general, existing documentation that uses System.Data.SqlClient on .NET Framework should now work with .NET Core, too.
+
+- [Develop using Always Encrypted with .NET Framework Data Provider](https://docs.microsoft.com/sql/relational-databases/security/encryption/develop-using-always-encrypted-with-net-framework-data-provider)
+- [Always Encrypted: Protect sensitive data and store encryption keys in the Windows certificate store](https://docs.microsoft.com/azure/sql-database/sql-database-always-encrypted)
+
+In order to use the enclave feature, the connection string should include the required attestation protocol and attestation URL.
+
+Example:
+
+- `Attestation Protocol=HGS;Enclave Attestation Url=`
diff --git a/release-notes/1.1/1.1.md b/release-notes/1.1/1.1.md
index 1c2df922b9..5ad6dca184 100644
--- a/release-notes/1.1/1.1.md
+++ b/release-notes/1.1/1.1.md
@@ -4,6 +4,7 @@ The following Microsoft.Data.SqlClient 1.1 stable releases have been shipped:
| Release Date | Version | Notes |
| :-- | :-- | :--: |
+| 2021/03/10 | 1.1.4 | [release notes](1.1.4.md) |
| 2020/05/15 | 1.1.3 | [release notes](1.1.3.md) |
| 2020/04/15 | 1.1.2 | [release notes](1.1.2.md) |
| 2020/02/14 | 1.1.1 | [release notes](1.1.1.md) |
diff --git a/release-notes/1.1/README.md b/release-notes/1.1/README.md
index 1c2df922b9..5ad6dca184 100644
--- a/release-notes/1.1/README.md
+++ b/release-notes/1.1/README.md
@@ -4,6 +4,7 @@ The following Microsoft.Data.SqlClient 1.1 stable releases have been shipped:
| Release Date | Version | Notes |
| :-- | :-- | :--: |
+| 2021/03/10 | 1.1.4 | [release notes](1.1.4.md) |
| 2020/05/15 | 1.1.3 | [release notes](1.1.3.md) |
| 2020/04/15 | 1.1.2 | [release notes](1.1.2.md) |
| 2020/02/14 | 1.1.1 | [release notes](1.1.1.md) |
diff --git a/release-notes/2.1/2.1.1.md b/release-notes/2.1/2.1.1.md
new file mode 100644
index 0000000000..35de2ed583
--- /dev/null
+++ b/release-notes/2.1/2.1.1.md
@@ -0,0 +1,75 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 2.1.1 released 18 December 2020
+
+This update brings the below changes over the previous stable release:
+
+### Fixed
+- Fixed issue with System-Assigned Managed Identity in Azure Functions [#841](https://github.com/dotnet/SqlClient/pull/841)
+- Fixed issue with Kerberos Authentication for .NET Core in Unix environments [#848](https://github.com/dotnet/SqlClient/pull/848)
+- Fixed issue with TCP Keep Alive for .NET Core in Unix environments [#855](https://github.com/dotnet/SqlClient/pull/855)
+
+### Target Platform Support
+
+- .NET Framework 4.6+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 2.1.1
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/2.1/2.1.2.md b/release-notes/2.1/2.1.2.md
new file mode 100644
index 0000000000..151607c779
--- /dev/null
+++ b/release-notes/2.1/2.1.2.md
@@ -0,0 +1,84 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 2.1.2 released 3 March 2021
+
+This update brings the below changes over the previous stable release:
+
+### Fixed
+- Fixed issue connecting with instance name from a Linux/macOS environment [#874](https://github.com/dotnet/SqlClient/pull/874)
+- Fixed wrong results issues by changing the timeout timer to ensure a correct execution state [#929](https://github.com/dotnet/SqlClient/pull/929)
+- Fixed a vulnerability by prohibiting `DtdProcessing` on `XmlTextReader` instances in .NET Core [#885](https://github.com/dotnet/SqlClient/pull/885)
+- Fixed Kerberos authentication when an SPN does not contain the port [#935](https://github.com/dotnet/SqlClient/pull/935)
+- Fixed missing error messages in Managed SNI [#883](https://github.com/dotnet/SqlClient/pull/883)
+- Fixed missing `System.Runtime.Caching` dependency for .NET Standard assemblies [#878](https://github.com/dotnet/SqlClient/pull/878)
+- Fixed event source tracing issues [#941](https://github.com/dotnet/SqlClient/pull/941)
+- Fixed MARS header contains errors issue against .NET Framework 4.8.1 [#928](https://github.com/dotnet/SqlClient/pull/928)
+
+
+
+### Target Platform Support
+
+- .NET Framework 4.6+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 2.1.1
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/2.1/2.1.3.md b/release-notes/2.1/2.1.3.md
new file mode 100644
index 0000000000..5034cfa306
--- /dev/null
+++ b/release-notes/2.1/2.1.3.md
@@ -0,0 +1,77 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 2.1.3 released 21 May 2021
+
+This update brings the below changes over the previous stable release:
+
+### Fixed
+
+- Fixed wrong data blended with transactions in .NET Core by marking a connection as doomed if the transaction completes or aborts while there is an open result set [#1051](https://github.com/dotnet/SqlClient/pull/1051)
+- Fixed race condition issues between SinglePhaseCommit and TransactionEnded events [#1049](https://github.com/dotnet/SqlClient/pull/1049)
+
+### Target Platform Support
+
+- .NET Framework 4.6+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 2.1.1
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/2.1/2.1.4.md b/release-notes/2.1/2.1.4.md
new file mode 100644
index 0000000000..77c3901166
--- /dev/null
+++ b/release-notes/2.1/2.1.4.md
@@ -0,0 +1,81 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 2.1.4 released 20 September 2021
+
+This update brings the below changes over the previous stable release:
+
+### Fixed
+
+- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1232](https://github.com/dotnet/SqlClient/pull/1232) [Read more](#ensure-connections-fail-when-encryption-is-required)
+- Fixed issue where connection goes to unusable state. [#1239](https://github.com/dotnet/SqlClient/pull/1239)
+
+### Target Platform Support
+
+- .NET Framework 4.6+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Ensure connections fail when encryption is required
+
+In scenarios where client encryption libraries were disabled or unavailable, it was possible for unencrypted connections to be made when Encrypt was set to true or the server required encryption.
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 2.1.1
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/2.1/2.1.5.md b/release-notes/2.1/2.1.5.md
new file mode 100644
index 0000000000..1617db1db9
--- /dev/null
+++ b/release-notes/2.1/2.1.5.md
@@ -0,0 +1,82 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 2.1.5 released 30 August 2022
+
+This update brings the below changes over the previous stable release:
+
+### Fixed
+
+- Added CommandText length validation when using stored procedure command types. [#1726](https://github.com/dotnet/SqlClient/pull/1726)
+- Fixed Kerberos authentication failure when using .NET 6. [#1727](https://github.com/dotnet/SqlClient/pull/1727)
+- Removed union overlay design and used reflection in `SqlTypeWorkarounds`. [#1729](https://github.com/dotnet/SqlClient/pull/1729)
+
+### Target Platform Support
+
+- .NET Framework 4.6+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Ensure connections fail when encryption is required
+
+In scenarios where client encryption libraries were disabled or unavailable, it was possible for unencrypted connections to be made when Encrypt was set to true or the server required encryption.
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 2.1.1
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/2.1/2.1.md b/release-notes/2.1/2.1.md
index 1be1be4fb0..2c149e041b 100644
--- a/release-notes/2.1/2.1.md
+++ b/release-notes/2.1/2.1.md
@@ -4,6 +4,11 @@ The following Microsoft.Data.SqlClient 2.1 stable releases have been shipped:
| Release Date | Version | Notes |
| :-- | :-- | :--: |
+| 2022/08/30 | 2.1.5 | [release notes](2.1.5.md) |
+| 2021/09/20 | 2.1.4 | [release notes](2.1.4.md) |
+| 2021/05/21 | 2.1.3 | [release notes](2.1.3.md) |
+| 2021/03/03 | 2.1.2 | [release notes](2.1.2.md) |
+| 2020/12/18 | 2.1.1 | [release notes](2.1.1.md) |
| 2020/11/19 | 2.1.0 | [release notes](2.1.0.md) |
The following Microsoft.Data.SqlClient 2.1 preview releases have been shipped:
diff --git a/release-notes/2.1/README.md b/release-notes/2.1/README.md
index 1be1be4fb0..2c149e041b 100644
--- a/release-notes/2.1/README.md
+++ b/release-notes/2.1/README.md
@@ -4,6 +4,11 @@ The following Microsoft.Data.SqlClient 2.1 stable releases have been shipped:
| Release Date | Version | Notes |
| :-- | :-- | :--: |
+| 2022/08/30 | 2.1.5 | [release notes](2.1.5.md) |
+| 2021/09/20 | 2.1.4 | [release notes](2.1.4.md) |
+| 2021/05/21 | 2.1.3 | [release notes](2.1.3.md) |
+| 2021/03/03 | 2.1.2 | [release notes](2.1.2.md) |
+| 2020/12/18 | 2.1.1 | [release notes](2.1.1.md) |
| 2020/11/19 | 2.1.0 | [release notes](2.1.0.md) |
The following Microsoft.Data.SqlClient 2.1 preview releases have been shipped:
diff --git a/release-notes/3.0/3.0.0-preview1.md b/release-notes/3.0/3.0.0-preview1.md
new file mode 100644
index 0000000000..39737afecf
--- /dev/null
+++ b/release-notes/3.0/3.0.0-preview1.md
@@ -0,0 +1,202 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 3.0.0-preview1.21075.2 released 15 March 2021
+
+This update brings the below changes over the previous release:
+
+### Breaking Changes over stable release v2.1
+- The minimum supported .NET Framework version has been increased to v4.6.1. .NET Framework v4.6.0 is no longer supported. [#899](https://github.com/dotnet/SqlClient/pull/899)
+
+### Added
+- Added support for Configurable Retry Logic [#693](https://github.com/dotnet/SqlClient/pull/693) [#966](https://github.com/dotnet/SqlClient/pull/966) [Read more](#configurable-retry-logic)
+- Added support for Event counters in .NET Core 3.1+ and .NET Standard 2.1+ [#719](https://github.com/dotnet/SqlClient/pull/719) [Read more](#event-counters)
+- Added support for Assembly Context Unloading in .NET Core [#913](https://github.com/dotnet/SqlClient/pull/913)
+- Added missing `System.Runtime.Caching` dependency for .NET Standard assemblies [#877](https://github.com/dotnet/SqlClient/pull/877)
+
+### Fixed
+- Fixed wrong results issues by changing the timeout timer to ensure a correct execution state [#906](https://github.com/dotnet/SqlClient/pull/906)
+- Fixed Kerberos authentication issues when configured Server Principal Name (SPN) didn't contain default port [#930](https://github.com/dotnet/SqlClient/pull/930)
+- Fixed MARS header errors when `MakeReadAsyncBlocking` App Context switch is set to `false` [#910](https://github.com/dotnet/SqlClient/pull/910) [#922](https://github.com/dotnet/SqlClient/pull/922)
+- Fixed unwanted exceptions being thrown from `SqlDataReader.Dispose` [#920](https://github.com/dotnet/SqlClient/pull/920)
+- Fixed issues connecting to SQL Server instance with instance name specified from Unix environment [#870](https://github.com/dotnet/SqlClient/pull/870)
+- Fixed TCP Keep Alive issues in .NET Core [#854](https://github.com/dotnet/SqlClient/pull/854)
+- Fixed Kerberos Authentication issues caused due to regression [#845](https://github.com/dotnet/SqlClient/pull/845)
+- Fixed issues with System-Assigned Managed Identity in Azure Functions [#829](https://github.com/dotnet/SqlClient/pull/829)
+- Fixed missing error messages in Managed SNI [#882](https://github.com/dotnet/SqlClient/pull/882)
+- Fixed event source trace string issue [#940](https://github.com/dotnet/SqlClient/pull/940)
+
+### Changes
+- Changed App Context switch `MakeReadAsyncBlocking` default to `false` [#937](https://github.com/dotnet/SqlClient/pull/937)
+- Replaced usage of `BinaryFormatter` with `DataContractSerializer` [#869](https://github.com/dotnet/SqlClient/pull/869)
+- Prohibited `DtdProcessing` on `XmlTextReader` instance in .NET Core [#884](https://github.com/dotnet/SqlClient/pull/884)
+- Improved performance by reducing memory allocations in `SerializeEncodingChar`/`WriteEncodingChar` and some options boxing [#785](https://github.com/dotnet/SqlClient/pull/785)
+- Improved performance by preventing orphaned active packets being GC'ed without clear [#888](https://github.com/dotnet/SqlClient/pull/888)
+- Various performance improvements [#889](https://github.com/dotnet/SqlClient/pull/889) [#900](https://github.com/dotnet/SqlClient/pull/900)
+- Partial event source tracing improvements in .NET Core [#867](https://github.com/dotnet/SqlClient/pull/867) [#897](https://github.com/dotnet/SqlClient/pull/897)
+- Changes to share common files between NetFx and NetCore source code [#827](https://github.com/dotnet/SqlClient/pull/827) [#835](https://github.com/dotnet/SqlClient/pull/835) [#838](https://github.com/dotnet/SqlClient/pull/838) [#881](https://github.com/dotnet/SqlClient/pull/881)
+
+
+## New features over stable release v2.1
+
+### Configurable Retry Logic
+
+This new feature introduces configurable support for client applications to retry on "transient" or "retriable" errors. Configuration can be done through code or app config files and retry operations can be applied to opening a connection or executing a command. This feature is disabled by default and is currently in preview. To enable this support, client applications must turn on the following safety switch:
+
+`AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableRetryLogic", true);`
+
+Once the .NET AppContext switch is enabled, a retry logic policy can be defined for `SqlConnection` and `SqlCommand` independently, or together using various customization options.
+
+New public APIs are introduced in `SqlConnection` and `SqlCommand` for registering a custom `SqlRetryLogicBaseProvider` implementation:
+
+```cs
+public SqlConnection
+{
+ public SqlRetryLogicBaseProvider RetryLogicProvider;
+}
+
+public SqlCommand
+{
+ public SqlRetryLogicBaseProvider RetryLogicProvider;
+}
+
+```
+
+API Usage examples can be found here:
+[SqlConnection retry sample](..\..\doc\samples\SqlConfigurableRetryLogic_OpenConnection.cs)
+[SqlCommand retry sample](..\..\doc\samples\SqlConfigurableRetryLogic_SqlCommand.cs)
+[Sample for retry logic options](..\..\doc\samples\SqlConfigurableRetryLogic_SqlRetryLogicOptions.cs)
+
+New configuration sections have also been introduced to do the same registration from configuration files, without having to modify existing code:
+
+```xml
+
+
+
+```
+
+A simple example of using the new configuration sections in configuration files is below:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Alternatively, applications can implement their own provider of the `SqlRetryLogicBaseProvider` base class, and register it with `SqlConnection`/`SqlCommand`.
+
+### Event Counters
+
+The following counters are now available for applications targeting .NET Core 3.1+ and .NET Standard 2.1+:
+
+- **HardConnects**: The number of physical connections that are being made.
+- **HardDisconnects**: The number of actual disconnects that are being made.
+- **ActiveHardConnections**: The number of active physical connections that are being made.
+- **SoftConnects**: The number of connections acquired from the pool.
+- **SoftDisconnects**: The number of connections returned to the pool.
+- **ActiveSoftConnections**: The total number of active pooled connections.
+- **NumberOfNonPooledConnections**: The total number of non-pooled connections.
+- **NumberOfPooledConnections**: The total number of pooled connections.
+- **NumberOfActiveConnectionPoolGroups**: The number of unique connection pool groups.
+- **NumberOfInactiveConnectionPoolGroups**: The number of unique connection pool groups to be pruned.
+- **NumberOfActiveConnectionPools**: The number of active connection pools.
+- **NumberOfInactiveConnectionPools**: The number of inactive connection pools.
+- **NumberOfActiveConnections**: The number of active connections currently in-use.
+- **NumberOfFreeConnections**: The number of free connections available for use.
+- **NumberOfStasisConnections**: The number of active free connections with open transactions.
+- **NumberOfReclaimedConnections**: The number of connections reclaimed from GC'd external connections.
+
+These counters can be used with .NET Core global CLI tools: `dotnet-counters` and `dotnet-trace` in Windows or Linux and PerfView in Windows, using `Microsoft.Data.SqlClient.EventSource` as the provider name.
+
+```cmd
+dotnet-counters monitor Microsoft.Data.SqlClient.EventSource -p
+PerfView /onlyProviders=*Microsoft.Data.SqlClient.EventSource:EventCounterIntervalSec=1 collect
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework 4.6.1
+
+- Microsoft.Data.SqlClient.SNI 2.1.1
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/3.0/3.0.0-preview2.md b/release-notes/3.0/3.0.0-preview2.md
new file mode 100644
index 0000000000..df52852bd7
--- /dev/null
+++ b/release-notes/3.0/3.0.0-preview2.md
@@ -0,0 +1,116 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 3.0.0-preview2.21106.5 released 16 April 2021
+
+This update brings the below changes over the previous release:
+
+### Breaking Changes over preview release V3.0.0-preview1
+- `User Id` connection property now requires `Client Id` instead of `Object Id` for **User-Assigned Managed Identity** [#1010](https://github.com/dotnet/SqlClient/pull/1010) [Read more](#azure-identity-dependency-introduction)
+- `SqlDataReader` now returns a `DBNull` value instead of an empty `byte[]`. Legacy behavior can be enabled by setting `AppContext` switch **Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior** [#998](https://github.com/dotnet/SqlClient/pull/998) [Read more](#enabling-row-version-null-behavior)
+
+### Added
+**Microsoft.Data.SqlClient** now depends on **Azure.Identity** library to acquire a token for "Active Directory Managed Identity/MSI" and "Active Directory Service Principal" authentication modes. [#1010](https://github.com/dotnet/SqlClient/pull/1010) [Read more](#azure-identity-dependency-introduction)
+- Upgraded Native SNI dependency to **v3.0.0-preview1** along with enhanced event tracing support [#1006](https://github.com/dotnet/SqlClient/pull/1006) [Read more](#event-tracing-improvements-in-sni.dll)
+
+### Fixed
+- Fixed wrong data blended with transactions in .NET Core by marking a connection as doomed if the transaction completes or aborts while there is an open result set [#1023](https://github.com/dotnet/SqlClient/pull/1023)
+- Fixed derived parameters containing incorrect typename [#1020](https://github.com/dotnet/SqlClient/pull/1020)
+- Fixed server connection leak possibilities when an exception occurs in pooling layer [#890](https://github.com/dotnet/SqlClient/pull/890)
+- Fixed IP connection resolving logic in .NET Core [#1016](https://github.com/dotnet/SqlClient/pull/1016) [#1031](https://github.com/dotnet/SqlClient/pull/1031)
+
+### Changed
+- Performance improvements in `SqlDateTime` to `DateTime` internal conversion method [#912](https://github.com/dotnet/SqlClient/pull/912)
+- Improved memory allocation by avoiding unnecessary context switching [1008](https://github.com/dotnet/SqlClient/pull/1008)
+- Updated `Microsoft.Identity.Client` version from **4.21.1** to **4.22.0** [#1036](https://github.com/dotnet/SqlClient/pull/1036)
+- Various performance improvements [#963](https://github.com/dotnet/SqlClient/pull/963) [#996](https://github.com/dotnet/SqlClient/pull/996) [#1004](https://github.com/dotnet/SqlClient/pull/1004) [#1012](https://github.com/dotnet/SqlClient/pull/1012) [#1017](https://github.com/dotnet/SqlClient/pull/1017)
+- Event source tracing improvements [#1018](https://github.com/dotnet/SqlClient/pull/1018)
+- Changes to share common files between NetFx and NetCore source code [#871](https://github.com/dotnet/SqlClient/pull/871) [#887](https://github.com/dotnet/SqlClient/pull/887)
+
+### Azure Identity dependency introduction
+**Microsoft.Data.SqlClient** now depends on the **Azure.Identity** library to acquire tokens for "Active Directory Managed Identity/MSI" and "Active Directory Service Principal" authentication modes. This change brings the following changes to the public surface area:
+
+- **Breaking Change**
+ The "User Id" connection property now requires "Client Id" instead of "Object Id" for "User-Assigned Managed Identity".
+- **Public API**
+ New read-only public property: `SqlAuthenticationParameters.ConnectionTimeout`
+- **Dependency**
+ Azure.Identity v1.3.0
+
+### Event tracing improvements in SNI.dll
+`Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) versions have been updated to `v3.0.0-preview1.21104.2`. Event tracing in SNI.dll will no longer be enabled through a client application. Subscribing a session to the **Microsoft.Data.SqlClient.EventSource** provider through tools like xperf or perfview will be sufficient.
+
+### Enabling row version null behavior
+`SqlDataReader` returns a `DBNull` value instead of an empty `byte[]`. To enable the legacy behavior, you must enable the following AppContext switch on application startup:
+**"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"**
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework 4.6.1
+
+- Microsoft.Data.SqlClient.SNI 3.0.0-preview1.21104.2
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/3.0/3.0.0-preview3.md b/release-notes/3.0/3.0.0-preview3.md
new file mode 100644
index 0000000000..6c213d0c3f
--- /dev/null
+++ b/release-notes/3.0/3.0.0-preview3.md
@@ -0,0 +1,176 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 3.0.0-preview3.21140.5 released 20 May 2021
+
+This update brings the below changes over the previous release:
+
+### Added
+
+- Added support for "Active Directory Default" authentication mode [#1043](https://github.com/dotnet/SqlClient/pull/1043) [Read more](#active-directory-default-authentication-support)
+- Added support for connection-level and command-level registration of custom key store providers to enable multi-tenant applications to control key store access [#1045](https://github.com/dotnet/SqlClient/pull/1045) [#1056](https://github.com/dotnet/SqlClient/pull/1056) [#1078](https://github.com/dotnet/SqlClient/pull/1078) [Read more](#custom-master-key-store-provider-registration-enhancements)
+- Added IP address preference support for TCP connections [#1015](https://github.com/dotnet/SqlClient/pull/1015) [Read more](#ip-address-preference)
+
+### Fixed
+
+- Fixed corrupted connection issue when an exception occurs during RPC execution with TVP types [#1068](https://github.com/dotnet/SqlClient/pull/1068)
+- Fixed race condition issues between SinglePhaseCommit and TransactionEnded events [#1042](https://github.com/dotnet/SqlClient/pull/1042)
+
+### Changed
+
+- Updated error messages for enclave exceptions to include a link to a troubleshooting guide. [#994](https://github.com/dotnet/SqlClient/pull/994)
+- Changes to share common files between projects [#1022](https://github.com/dotnet/SqlClient/pull/1022) [#1038](https://github.com/dotnet/SqlClient/pull/1038) [#1040](https://github.com/dotnet/SqlClient/pull/1040) [#1033](https://github.com/dotnet/SqlClient/pull/1033) [#1028](https://github.com/dotnet/SqlClient/pull/1028) [#1039](https://github.com/dotnet/SqlClient/pull/1039)
+
+### Active Directory Default authentication support
+
+This PR introduces a new SQL Authentication method, **Active Directory Default**. This authentication mode widens the possibilities of user authentication, extending login solutions to the client environment, Visual Studio Code, Visual Studio, Azure CLI etc.
+
+With this authentication mode, the driver acquires a token by passing "[DefaultAzureCredential](https://docs.microsoft.com/dotnet/api/azure.identity.defaultazurecredential)" from the Azure Identity library to acquire an access token. This mode attempts to use these credential types to acquire an access token in the following order:
+
+- **EnvironmentCredential**
+ - Enables authentication to Azure Active Directory using client and secret, or username and password, details configured in the following environment variables: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME, AZURE_PASSWORD ([More details](https://docs.microsoft.com/dotnet/api/azure.identity.environmentcredential))
+- **ManagedIdentityCredential**
+ - Attempts authentication to Azure Active Directory using a managed identity that has been assigned to the deployment environment. **"Client Id" of "User Assigned Managed Identity"** is read from the **"User Id" connection property**.
+- **SharedTokenCacheCredential**
+ - Authenticates using tokens in the local cache shared between Microsoft applications.
+- **VisualStudioCredential**
+ - Enables authentication to Azure Active Directory using data from Visual Studio
+- **VisualStudioCodeCredential**
+ - Enables authentication to Azure Active Directory using data from Visual Studio Code.
+- **AzureCliCredential**
+ - Enables authentication to Azure Active Directory using Azure CLI to obtain an access token.
+
+> InteractiveBrowserCredential is disabled in the driver implementation of "Active Directory Default", and "Active Directory Interactive" is the only option available to acquire a token using MFA/Interactive authentication.*
+
+> Further customization options are not available at the moment.
+
+### Custom master key store provider registration enhancements
+
+Microsoft.Data.SqlClient now offers more control of where master key store providers are accessible in an application in order to better support multi-tenant applications and their use of column encryption/decryption. The following APIs are introduced to allow registration of custom master key store providers on instances of `SqlConnection` and `SqlCommand`:
+
+```cs
+public class SqlConnection
+{
+ public void RegisterColumnEncryptionKeyStoreProvidersOnConnection(IDictionary customProviders)
+}
+public class SqlCommand
+{
+ public void RegisterColumnEncryptionKeyStoreProvidersOnCommand(IDictionary customProviders)
+}
+```
+
+The static API on `SqlConnection`, i.e. `SqlConnection.RegisterColumnEncryptionKeyStoreProviders` to register custom master key store providers globally continues to be supported. The column encryption key cache maintained globally only applies to globally registered providers.
+
+#### Column master key store provider registration precedence
+
+The built-in column master key store providers that are available for the Windows Certificate Store, CNG Store and CSP are pre-registered. No providers should be registered on the connection or command instances if one of the built-in column master key store providers is needed.
+
+Custom master key store providers can be registered with the driver at three different layers. The global level is as it currently is. The new per-connection and per-command level registrations will be empty initially and can be set more than once.
+
+The precedence of the three registrations are as follows:
+
+- The per-command registration will be checked if it is not empty.
+- If the per-command registration is empty, the per-connection registration will be checked if it is not empty.
+- If the per-connection registration is empty, the global registration will be checked.
+
+Once any key store provider is found at a registration level, the driver will **NOT** fall back to the other registrations to search for a provider. If providers are registered but the proper provider is not found at a level, an exception will be thrown containing only the registered providers in the registration that was checked.
+
+#### Column encryption key cache precedence
+
+The column encryption keys (CEKs) for custom key store providers registered using the new instance-level APIs will not be cached by the driver. The key store providers need to implement their own cache to gain performance. This local cache of column encryption keys implemented by custom key store providers will be disabled by the driver if the key store provider instance is registered in the driver at the global level.
+
+A new API has also been introduced on the `SqlColumnEncryptionKeyStoreProvider` base class to set the cache time to live:
+
+```cs
+public abstract class SqlColumnEncryptionKeyStoreProvider
+{
+ // The default value of Column Encryption Key Cache Time to Live is 0.
+ // Provider's local cache is disabled for globally registered providers.
+ // Custom key store provider implementation must include column encryption key cache to provide caching support to locally registered providers.
+ public virtual TimeSpan? ColumnEncryptionKeyCacheTtl { get; set; } = new TimeSpan(0);
+}
+```
+
+### IP Address preference
+
+A new connection property `IPAddressPreference` is introduced to specify the IP address family preference to the driver when establishing TCP connections. If `Transparent Network IP Resolution` (in .NET Framework) or `Multi Subnet Failover` is set to `true`, this setting has no effect. Below are the three accepted values for this property:
+
+- **IPv4First**
+ - This is the default preference value. The driver will use resolved IPv4 addresses first. If none of them can be connected to successfully, it will try resolved IPv6 addresses.
+
+- **IPv6First**
+ - The driver will use resolved IPv6 addresses first. If none of them can be connected to successfully, it will try resolved IPv4 addresses.
+
+- **UsePlatformDefault**
+ - The driver will try IP addresses in the order received from the DNS resolution response.
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework 4.6.1
+
+- Microsoft.Data.SqlClient.SNI 3.0.0-preview1.21104.2
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0-preview1.21104.2
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/3.0/3.0.0.md b/release-notes/3.0/3.0.0.md
new file mode 100644
index 0000000000..ef090c2f3c
--- /dev/null
+++ b/release-notes/3.0/3.0.0.md
@@ -0,0 +1,346 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 3.0.0 released 09 June 2021
+
+This update brings the below changes over the previous preview release:
+
+### Added
+
+- Added support for column encryption key caching when the server supports retrying queries that require enclave computations [#1062](https://github.com/dotnet/SqlClient/pull/1062)
+- Added support for configurable retry logic configuration file in .NET Standard [#1090](https://github.com/dotnet/SqlClient/pull/1090)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v3.0.0` [#1102](https://github.com/dotnet/SqlClient/pull/1102)
+- Improved event counter display information [#1091](https://github.com/dotnet/SqlClient/pull/1091)
+
+### Breaking Changes
+
+- Modified column encryption key store provider registrations to give built-in system providers precedence over providers registered on connection and command instances. [#1101](https://github.com/dotnet/SqlClient/pull/1101)
+
+## Summary of changes in 3.0
+
+All changes in Microsoft.Data.SqlClient v3.0 over v2.1:
+
+### New Additions
+
+- Added support for Configurable Retry Logic [#693](https://github.com/dotnet/SqlClient/pull/693) [#966](https://github.com/dotnet/SqlClient/pull/966) [Read more](#configurable-retry-logic)
+- Added support for Event counters in .NET Core 3.1+ and .NET Standard 2.1+ [#719](https://github.com/dotnet/SqlClient/pull/719) [Read more](#event-counters)
+- Added support for Assembly Context Unloading in .NET Core [#913](https://github.com/dotnet/SqlClient/pull/913)
+- Added missing `System.Runtime.Caching` dependency for .NET Standard assemblies [#877](https://github.com/dotnet/SqlClient/pull/877)
+- **Microsoft.Data.SqlClient** now depends on **Azure.Identity** library to acquire a token for "Active Directory Managed Identity/MSI" and "Active Directory Service Principal" authentication modes. [#1010](https://github.com/dotnet/SqlClient/pull/1010) [Read more](#azure-identity-dependency-introduction)
+- Upgraded Native SNI dependency to **v3.0.0-preview1** along with enhanced event tracing support [#1006](https://github.com/dotnet/SqlClient/pull/1006) [Read more](#event-tracing-improvements-in-sni.dll)
+- Added support for "Active Directory Default" authentication mode [#1043](https://github.com/dotnet/SqlClient/pull/1043) [Read more](#active-directory-default-authentication-support)
+- Added support for connection-level and command-level registration of custom key store providers to enable multi-tenant applications to control key store access [#1045](https://github.com/dotnet/SqlClient/pull/1045) [#1056](https://github.com/dotnet/SqlClient/pull/1056) [#1078](https://github.com/dotnet/SqlClient/pull/1078) [Read more](#custom-master-key-store-provider-registration-enhancements)
+- Added IP address preference support for TCP connections [#1015](https://github.com/dotnet/SqlClient/pull/1015) [Read more](#ip-address-preference)
+
+### Bug Fixes
+
+- Fixed wrong results issues by changing the timeout timer to ensure a correct execution state [#906](https://github.com/dotnet/SqlClient/pull/906)
+- Fixed Kerberos authentication issues when configured Server Principal Name (SPN) didn't contain default port [#930](https://github.com/dotnet/SqlClient/pull/930)
+- Fixed MARS header errors when `MakeReadAsyncBlocking` App Context switch is set to `false` [#910](https://github.com/dotnet/SqlClient/pull/910) [#922](https://github.com/dotnet/SqlClient/pull/922)
+- Fixed unwanted exceptions being thrown from `SqlDataReader.Dispose` [#920](https://github.com/dotnet/SqlClient/pull/920)
+- Fixed issues connecting to SQL Server instance with instance name specified from Unix environment [#870](https://github.com/dotnet/SqlClient/pull/870)
+- Fixed TCP Keep Alive issues in .NET Core [#854](https://github.com/dotnet/SqlClient/pull/854)
+- Fixed Kerberos Authentication issues caused due to regression [#845](https://github.com/dotnet/SqlClient/pull/845)
+- Fixed issues with System-Assigned Managed Identity in Azure Functions [#829](https://github.com/dotnet/SqlClient/pull/829)
+- Fixed missing error messages in Managed SNI [#882](https://github.com/dotnet/SqlClient/pull/882)
+- Fixed event source trace string issue [#940](https://github.com/dotnet/SqlClient/pull/940)
+- Fixed wrong data blended with transactions in .NET Core by marking a connection as doomed if the transaction completes or aborts while there is an open result set [#1023](https://github.com/dotnet/SqlClient/pull/1023)
+- Fixed derived parameters containing incorrect typename [#1020](https://github.com/dotnet/SqlClient/pull/1020)
+- Fixed server connection leak possibilities when an exception occurs in pooling layer [#890](https://github.com/dotnet/SqlClient/pull/890)
+- Fixed IP connection resolving logic in .NET Core [#1016](https://github.com/dotnet/SqlClient/pull/1016) [#1031](https://github.com/dotnet/SqlClient/pull/1031)
+- Fixed corrupted connection issue when an exception occurs during RPC execution with TVP types [#1068](https://github.com/dotnet/SqlClient/pull/1068)
+- Fixed race condition issues between SinglePhaseCommit and TransactionEnded events [#1042](https://github.com/dotnet/SqlClient/pull/1042)
+
+### Improvements and Changes
+
+- Changed App Context switch `MakeReadAsyncBlocking` default to `false` [#937](https://github.com/dotnet/SqlClient/pull/937)
+- Replaced usage of `BinaryFormatter` with `DataContractSerializer` [#869](https://github.com/dotnet/SqlClient/pull/869)
+- Prohibited `DtdProcessing` on `XmlTextReader` instance in .NET Core [#884](https://github.com/dotnet/SqlClient/pull/884)
+- Improved performance by reducing memory allocations in `SerializeEncodingChar`/`WriteEncodingChar` and some options boxing [#785](https://github.com/dotnet/SqlClient/pull/785)
+- Improved performance by preventing orphaned active packets being GC'ed without clear [#888](https://github.com/dotnet/SqlClient/pull/888)
+- Various performance improvements [#889](https://github.com/dotnet/SqlClient/pull/889) [#900](https://github.com/dotnet/SqlClient/pull/900)
+- Partial event source tracing improvements in .NET Core [#867](https://github.com/dotnet/SqlClient/pull/867) [#897](https://github.com/dotnet/SqlClient/pull/897)
+- Changes to share common files between NetFx and NetCore source code [#827](https://github.com/dotnet/SqlClient/pull/827) [#835](https://github.com/dotnet/SqlClient/pull/835) [#838](https://github.com/dotnet/SqlClient/pull/838) [#881](https://github.com/dotnet/SqlClient/pull/881)
+- Performance improvements in `SqlDateTime` to `DateTime` internal conversion method [#912](https://github.com/dotnet/SqlClient/pull/912)
+- Improved memory allocation by avoiding unnecessary context switching [1008](https://github.com/dotnet/SqlClient/pull/1008)
+- Updated `Microsoft.Identity.Client` version from **4.21.1** to **4.22.0** [#1036](https://github.com/dotnet/SqlClient/pull/1036)
+- Various performance improvements [#963](https://github.com/dotnet/SqlClient/pull/963) [#996](https://github.com/dotnet/SqlClient/pull/996) [#1004](https://github.com/dotnet/SqlClient/pull/1004) [#1012](https://github.com/dotnet/SqlClient/pull/1012) [#1017](https://github.com/dotnet/SqlClient/pull/1017)
+- Event source tracing improvements [#1018](https://github.com/dotnet/SqlClient/pull/1018)
+- Changes to share common files between NetFx and NetCore source code [#871](https://github.com/dotnet/SqlClient/pull/871) [#887](https://github.com/dotnet/SqlClient/pull/887)
+- Updated error messages for enclave exceptions to include a link to a troubleshooting guide. [#994](https://github.com/dotnet/SqlClient/pull/994)
+- Changes to share common files between projects [#1022](https://github.com/dotnet/SqlClient/pull/1022) [#1038](https://github.com/dotnet/SqlClient/pull/1038) [#1040](https://github.com/dotnet/SqlClient/pull/1040) [#1033](https://github.com/dotnet/SqlClient/pull/1033) [#1028](https://github.com/dotnet/SqlClient/pull/1028) [#1039](https://github.com/dotnet/SqlClient/pull/1039)
+
+### Breaking Changes
+
+- The minimum supported .NET Framework version has been increased to v4.6.1. .NET Framework v4.6.0 is no longer supported. [#899](https://github.com/dotnet/SqlClient/pull/899)
+- `User Id` connection property now requires `Client Id` instead of `Object Id` for **User-Assigned Managed Identity** [#1010](https://github.com/dotnet/SqlClient/pull/1010) [Read more](#azure-identity-dependency-introduction)
+- `SqlDataReader` now returns a `DBNull` value instead of an empty `byte[]`. Legacy behavior can be enabled by setting `AppContext` switch **Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior** [#998](https://github.com/dotnet/SqlClient/pull/998) [Read more](#enabling-row-version-null-behavior)
+
+### Configurable Retry Logic
+
+This new feature introduces configurable support for client applications to retry on "transient" or "retriable" errors. Configuration can be done through code or app config files and retry operations can be applied to opening a connection or executing a command. This feature is disabled by default and is currently in preview. To enable this support, client applications must turn on the following safety switch:
+
+`AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableRetryLogic", true);`
+
+Once the .NET AppContext switch is enabled, a retry logic policy can be defined for `SqlConnection` and `SqlCommand` independently, or together using various customization options.
+
+New public APIs are introduced in `SqlConnection` and `SqlCommand` for registering a custom `SqlRetryLogicBaseProvider` implementation:
+
+```cs
+public SqlConnection
+{
+ public SqlRetryLogicBaseProvider RetryLogicProvider;
+}
+
+public SqlCommand
+{
+ public SqlRetryLogicBaseProvider RetryLogicProvider;
+}
+
+```
+
+API Usage examples can be found here:
+
+[SqlConnection retry sample](../../doc/samples/SqlConfigurableRetryLogic_OpenConnection.cs)
+
+[SqlCommand retry sample](../../doc/samples/SqlConfigurableRetryLogic_SqlCommand.cs)
+
+[Sample for retry logic options](../../doc/samples/SqlConfigurableRetryLogic_SqlRetryLogicOptions.cs)
+
+New configuration sections have also been introduced to do the same registration from configuration files, without having to modify existing code:
+
+```xml
+
+
+
+```
+
+A simple example of using the new configuration sections in configuration files is below:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Alternatively, applications can implement their own provider of the `SqlRetryLogicBaseProvider` base class, and register it with `SqlConnection`/`SqlCommand`.
+
+### Event Counters
+
+The following counters are now available for applications targeting .NET Core 3.1+ and .NET Standard 2.1+:
+
+|Name|Display name|Description|
+|-------------------------|-----------------|-----------------|
+|**active-hard-connections**|Actual active connections currently made to servers|The number of connections that are currently open to database servers.|
+|**hard-connects**|Actual connection rate to servers|The number of connections per second that are being opened to database servers.|
+|**hard-disconnects**|Actual disconnection rate from servers|The number of disconnects per second that are being made to database servers.|
+|**active-soft-connects**|Active connections retrieved from the connection pool|The number of already-open connections being consumed from the connection pool.|
+|**soft-connects**|Rate of connections retrieved from the connection pool|The number of connections per second that are being consumed from the connection pool.|
+|**soft-disconnects**|Rate of connections returned to the connection pool|The number of connections per second that are being returned to the connection pool.|
+|**number-of-non-pooled-connections**|Number of connections not using connection pooling|The number of active connections that aren't pooled.|
+|**number-of-pooled-connections**|Number of connections managed by the connection pool|The number of active connections that are being managed by the connection pooling infrastructure.|
+|**number-of-active-connection-pool-groups**|Number of active unique connection strings|The number of unique connection pool groups that are active. This counter is controlled by the number of unique connection strings that are found in the AppDomain.|
+|**number-of-inactive-connection-pool-groups**|Number of unique connection strings waiting for pruning|The number of unique connection pool groups that are marked for pruning. This counter is controlled by the number of unique connection strings that are found in the AppDomain.|
+|**number-of-active-connection-pools**|Number of active connection pools|The total number of connection pools.|
+|**number-of-inactive-connection-pools**|Number of inactive connection pools|The number of inactive connection pools that haven't had any recent activity and are waiting to be disposed.|
+|**number-of-active-connections**|Number of active connections|The number of active connections that are currently in use.|
+|**number-of-free-connections**|Number of ready connections in the connection pool|The number of open connections available for use in the connection pools.|
+|**number-of-stasis-connections**|Number of connections currently waiting to be ready|The number of connections currently awaiting completion of an action and which are unavailable for use by the application.|
+|**number-of-reclaimed-connections**|Number of reclaimed connections from GC|The number of connections that have been reclaimed through garbage collection where `Close` or `Dispose` wasn't called by the application. **Note** Not explicitly closing or disposing connections hurts performance.|
+
+These counters can be used with .NET Core global CLI tools: `dotnet-counters` and `dotnet-trace` in Windows or Linux and PerfView in Windows, using `Microsoft.Data.SqlClient.EventSource` as the provider name. For more information, see [Retrieve event counter values](https://docs.microsoft.com/en-us/sql/connect/ado-net/event-counters#retrieve-event-counter-values).
+
+```cmd
+dotnet-counters monitor Microsoft.Data.SqlClient.EventSource -p
+PerfView /onlyProviders=*Microsoft.Data.SqlClient.EventSource:EventCounterIntervalSec=1 collect
+```
+
+### Azure Identity dependency introduction
+**Microsoft.Data.SqlClient** now depends on the **Azure.Identity** library to acquire tokens for "Active Directory Managed Identity/MSI" and "Active Directory Service Principal" authentication modes. This change brings the following changes to the public surface area:
+
+- **Breaking Change**
+ The "User Id" connection property now requires "Client Id" instead of "Object Id" for "User-Assigned Managed Identity".
+- **Public API**
+ New read-only public property: `SqlAuthenticationParameters.ConnectionTimeout`
+- **Dependency**
+ Azure.Identity v1.3.0
+
+### Event tracing improvements in SNI.dll
+`Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) versions have been updated to `v3.0.0-preview1.21104.2`. Event tracing in SNI.dll will no longer be enabled through a client application. Subscribing a session to the **Microsoft.Data.SqlClient.EventSource** provider through tools like xperf or perfview will be sufficient. For more information, see [Event tracing support in Native SNI](https://docs.microsoft.com/en-us/sql/connect/ado-net/enable-eventsource-tracing#event-tracing-support-in-native-sni).
+
+### Enabling row version null behavior
+`SqlDataReader` returns a `DBNull` value instead of an empty `byte[]`. To enable the legacy behavior, you must enable the following AppContext switch on application startup:
+**"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior"**
+
+### Active Directory Default authentication support
+
+This PR introduces a new SQL Authentication method, **Active Directory Default**. This authentication mode widens the possibilities of user authentication, extending login solutions to the client environment, Visual Studio Code, Visual Studio, Azure CLI etc.
+
+With this authentication mode, the driver acquires a token by passing "[DefaultAzureCredential](https://docs.microsoft.com/dotnet/api/azure.identity.defaultazurecredential)" from the Azure Identity library to acquire an access token. This mode attempts to use these credential types to acquire an access token in the following order:
+
+- **EnvironmentCredential**
+ - Enables authentication to Azure Active Directory using client and secret, or username and password, details configured in the following environment variables: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_USERNAME, AZURE_PASSWORD ([More details](https://docs.microsoft.com/dotnet/api/azure.identity.environmentcredential))
+- **ManagedIdentityCredential**
+ - Attempts authentication to Azure Active Directory using a managed identity that has been assigned to the deployment environment. **"Client Id" of "User Assigned Managed Identity"** is read from the **"User Id" connection property**.
+- **SharedTokenCacheCredential**
+ - Authenticates using tokens in the local cache shared between Microsoft applications.
+- **VisualStudioCredential**
+ - Enables authentication to Azure Active Directory using data from Visual Studio
+- **VisualStudioCodeCredential**
+ - Enables authentication to Azure Active Directory using data from Visual Studio Code.
+- **AzureCliCredential**
+ - Enables authentication to Azure Active Directory using Azure CLI to obtain an access token.
+
+> InteractiveBrowserCredential is disabled in the driver implementation of "Active Directory Default", and "Active Directory Interactive" is the only option available to acquire a token using MFA/Interactive authentication.*
+
+> Further customization options are not available at the moment.
+
+### Custom master key store provider registration enhancements
+
+Microsoft.Data.SqlClient now offers more control of where master key store providers are accessible in an application in order to better support multi-tenant applications and their use of column encryption/decryption. The following APIs are introduced to allow registration of custom master key store providers on instances of `SqlConnection` and `SqlCommand`:
+
+```cs
+public class SqlConnection
+{
+ public void RegisterColumnEncryptionKeyStoreProvidersOnConnection(IDictionary customProviders)
+}
+public class SqlCommand
+{
+ public void RegisterColumnEncryptionKeyStoreProvidersOnCommand(IDictionary customProviders)
+}
+```
+
+The static API on `SqlConnection`, i.e. `SqlConnection.RegisterColumnEncryptionKeyStoreProviders` to register custom master key store providers globally continues to be supported. The column encryption key cache maintained globally only applies to globally registered providers.
+
+#### Column master key store provider registration precedence
+
+The built-in column master key store providers that are available for the Windows Certificate Store, CNG Store and CSP are pre-registered. No providers should be registered on the connection or command instances if one of the built-in column master key store providers is needed.
+
+Custom master key store providers can be registered with the driver at three different layers. The global level is as it currently is. The new per-connection and per-command level registrations will be empty initially and can be set more than once.
+
+The precedence of the three registrations are as follows:
+
+- The per-command registration will be checked if it is not empty.
+- If the per-command registration is empty, the per-connection registration will be checked if it is not empty.
+- If the per-connection registration is empty, the global registration will be checked.
+
+Once any key store provider is found at a registration level, the driver will **NOT** fall back to the other registrations to search for a provider. If providers are registered but the proper provider is not found at a level, an exception will be thrown containing only the registered providers in the registration that was checked.
+
+#### Column encryption key cache precedence
+
+The column encryption keys (CEKs) for custom key store providers registered using the new instance-level APIs will not be cached by the driver. The key store providers need to implement their own cache to gain performance. This local cache of column encryption keys implemented by custom key store providers will be disabled by the driver if the key store provider instance is registered in the driver at the global level.
+
+A new API has also been introduced on the `SqlColumnEncryptionKeyStoreProvider` base class to set the cache time to live:
+
+```cs
+public abstract class SqlColumnEncryptionKeyStoreProvider
+{
+ // The default value of Column Encryption Key Cache Time to Live is 0.
+ // Provider's local cache is disabled for globally registered providers.
+ // Custom key store provider implementation must include column encryption key cache to provide caching support to locally registered providers.
+ public virtual TimeSpan? ColumnEncryptionKeyCacheTtl { get; set; } = new TimeSpan(0);
+}
+```
+
+### IP Address preference
+
+A new connection property `IPAddressPreference` is introduced to specify the IP address family preference to the driver when establishing TCP connections. If `Transparent Network IP Resolution` (in .NET Framework) or `Multi Subnet Failover` is set to `true`, this setting has no effect. Below are the three accepted values for this property:
+
+- **IPv4First**
+ - This is the default preference value. The driver will use resolved IPv4 addresses first. If none of them can be connected to successfully, it will try resolved IPv6 addresses.
+
+- **IPv6First**
+ - The driver will use resolved IPv6 addresses first. If none of them can be connected to successfully, it will try resolved IPv4 addresses.
+
+- **UsePlatformDefault**
+ - The driver will try IP addresses in the order received from the DNS resolution response.
+
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 3.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Loader 4.3.0
diff --git a/release-notes/3.0/3.0.1.md b/release-notes/3.0/3.0.1.md
new file mode 100644
index 0000000000..177ec32e25
--- /dev/null
+++ b/release-notes/3.0/3.0.1.md
@@ -0,0 +1,87 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 3.0.1 released 24 September 2021
+
+This update brings the below changes over the previous stable release:
+
+### Fixed
+
+- Fixed async thread blocking issues on `SqlConnection.Open()` for active directory authentication modes. [#1270](https://github.com/dotnet/SqlClient/pull/1270)
+- Fixed unknown transaction state issues when promoting delegated transaction. [1247](https://github.com/dotnet/SqlClient/pull/1247)
+- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1233](https://github.com/dotnet/SqlClient/pull/1233) [Read more](#ensure-connections-fail-when-encryption-is-required)
+- Fixed bug with `LegacyRowVersionNullBehavior` App Context switch. [#1246](https://github.com/dotnet/SqlClient/pull/1246)
+- Fixed recursive calls to `RetryLogicProvider` when calling `SqlCommand.ExecuteScalarAsync`. [#1245](https://github.com/dotnet/SqlClient/pull/1245)
+- Fixed async deadlock scenarios in web contexts with configurable retry logic provider. [#1245](https://github.com/dotnet/SqlClient/pull/1245)
+- Fixed deadlock in transaction using .NET Framework. [#1243](https://github.com/dotnet/SqlClient/pull/1243)
+- Fixed issue where connection goes to unusable state. [#1238](https://github.com/dotnet/SqlClient/pull/1238)
+
+### Ensure connections fail when encryption is required
+
+In scenarios where client encryption libraries were disabled or unavailable, it was possible for unencrypted connections to be made when Encrypt was set to true or the server required encryption.
+
+### Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 2.1.1
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.0
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 2.1.1
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Runtime.Caching 4.7.0
+- Microsoft.Identity.Client 4.21.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
diff --git a/release-notes/3.0/3.0.md b/release-notes/3.0/3.0.md
new file mode 100644
index 0000000000..e35ae11698
--- /dev/null
+++ b/release-notes/3.0/3.0.md
@@ -0,0 +1,16 @@
+# Microsoft.Data.SqlClient 3.0 Releases
+
+The following Microsoft.Data.SqlClient 3.0 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2021/09/24 | 3.0.1 | [release notes](3.0.1.md) |
+| 2021/06/09 | 3.0.0 | [release notes](3.0.0.md) |
+
+The following Microsoft.Data.SqlClient 3.0 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2021/05/20 | 3.0.0-preview3.21140.5 | [release notes](3.0.0-preview3.md) |
+| 2021/04/15 | 3.0.0-preview2.21106.5 | [release notes](3.0.0-preview2.md) |
+| 2021/03/15 | 3.0.0-preview1.21075.2 | [release notes](3.0.0-preview1.md) |
diff --git a/release-notes/3.0/README.md b/release-notes/3.0/README.md
new file mode 100644
index 0000000000..0d7f9e97da
--- /dev/null
+++ b/release-notes/3.0/README.md
@@ -0,0 +1,16 @@
+# Microsoft.Data.SqlClient 3.0 Releases
+
+The following Microsoft.Data.SqlClient 3.0 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2021/09/24 | 3.0.1 | [Release notes](3.0.1.md) |
+| 2021/06/09 | 3.0.0 | [release notes](3.0.0.md) |
+
+The following Microsoft.Data.SqlClient 3.0 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2021/05/20 | 3.0.0-preview3.21140.5 | [release notes](3.0.0-preview3.md) |
+| 2021/04/15 | 3.0.0-preview2.21106.5 | [release notes](3.0.0-preview2.md) |
+| 2021/03/15 | 3.0.0-preview1.21075.2 | [release notes](3.0.0-preview1.md) |
diff --git a/release-notes/3.1/3.1.0.md b/release-notes/3.1/3.1.0.md
new file mode 100644
index 0000000000..eba2ad30d0
--- /dev/null
+++ b/release-notes/3.1/3.1.0.md
@@ -0,0 +1,75 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 3.1.0 released 30 March 2022
+
+This update includes the following changes over the 3.0 release:
+
+### Added
+
+- Added new Attestation Protocol `None` for `VBS` enclave types. This protocol will allow users to forgo enclave attestation for VBS enclaves. [#1539](https://github.com/dotnet/SqlClient/pull/1539) [Read more](#introduce-attestation-protocol-none)
+- Included `42108` and `42109` error codes to retriable transient errors list. [#1560](https://github.com/dotnet/SqlClient/pull/1560)
+
+### Fixed
+
+- Changed EnclaveDelegate.Crypto GetEnclaveProvider to use a thread safe concurrent dictionary. [#1564](https://github.com/dotnet/SqlClient/pull/1564)
+
+### Introduce Attestation Protocol None
+
+A new attestation protocol called `None` will be allowed in the connection string. This protocol will allow users to forgo enclave attestation for `VBS` enclaves. When this protocol is set, the enclave attestation URL property is optional.
+
+Connection string example:
+
+```cs
+//Attestation protocol NONE with no URL
+"Data Source = {server}; Initial Catalog = {db}; Column Encryption Setting = Enabled; Attestation Protocol = None;"
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 3.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Loader 4.3.0
diff --git a/release-notes/3.1/3.1.1.md b/release-notes/3.1/3.1.1.md
new file mode 100644
index 0000000000..d7cb669712
--- /dev/null
+++ b/release-notes/3.1/3.1.1.md
@@ -0,0 +1,77 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 3.1.1 released 12 August 2022
+
+This update brings the below changes over the previous release:
+
+### Fixed
+
+- Fixed null SqlBinary as rowversion. [#1700](https://github.com/dotnet/SqlClient/pull/1700)
+- Fixed Kerberos authentication failure when using .NET 6. [#1696](https://github.com/dotnet/SqlClient/pull/1696)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1695](https://github.com/dotnet/SqlClient/pull/1695)
+- Removed union overlay design and use reflection in `SqlTypeWorkarounds`. [#1699](https://github.com/dotnet/SqlClient/pull/1699)
+
+## Target Platform Support
+
+- .NET Framework 4.6+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework 4.61
+
+- Microsoft.Data.SqlClient.SNI 3.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core 2.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+
+#### .NET Core 3.1
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Diagnostics.DiagnosticSource 4.7.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 3.0.0
+- Microsoft.Win32.Registry 4.7.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 4.7.0
+- System.Text.Encoding.CodePages 4.7.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.Caching 4.7.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.14.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 5.6.0
+- Microsoft.IdentityModel.JsonWebTokens 5.6.0
+- System.Configuration.ConfigurationManager 4.7.0
+- System.Runtime.Loader 4.3.0
diff --git a/release-notes/3.1/3.1.md b/release-notes/3.1/3.1.md
new file mode 100644
index 0000000000..6e4d68e534
--- /dev/null
+++ b/release-notes/3.1/3.1.md
@@ -0,0 +1,8 @@
+# Microsoft.Data.SqlClient 3.1 Releases
+
+The following Microsoft.Data.SqlClient 3.1 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/08/12 | 3.1.1 | [release notes](3.1.1.md) |
+| 2022/03/30 | 3.1.0 | [release notes](3.1.0.md) |
diff --git a/release-notes/3.1/README.md b/release-notes/3.1/README.md
new file mode 100644
index 0000000000..6e4d68e534
--- /dev/null
+++ b/release-notes/3.1/README.md
@@ -0,0 +1,8 @@
+# Microsoft.Data.SqlClient 3.1 Releases
+
+The following Microsoft.Data.SqlClient 3.1 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/08/12 | 3.1.1 | [release notes](3.1.1.md) |
+| 2022/03/30 | 3.1.0 | [release notes](3.1.0.md) |
diff --git a/release-notes/4.0/4.0.0-preview1.md b/release-notes/4.0/4.0.0-preview1.md
new file mode 100644
index 0000000000..459462ca48
--- /dev/null
+++ b/release-notes/4.0/4.0.0-preview1.md
@@ -0,0 +1,113 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.0.0-preview1.21237.2 released 25 August 2021
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over stable release 3.0.0
+- Changed `Encrypt` connection string property to be `true` by default. [#1210](https://github.com/dotnet/SqlClient/pull/1210) [Read more](#encrypt-default-value-set-to-true)
+- The driver now throws `SqlException` replacing `AggregateException` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213)
+- Dropped obsolete `Asynchronous Processing` connection property from .NET Framework. [#1148](https://github.com/dotnet/SqlClient/pull/1148)
+
+### Added
+- Added `SqlCommand.EnableOptimizedParameterBinding` property that when enabled increases performance for commands with very large numbers of parameters. [#1041](https://github.com/dotnet/SqlClient/pull/1041) [Read more](#enable-optimized-parameter-binding)
+- Included `42108` and `42109` error codes to retriable transient errors list. [#1215](https://github.com/dotnet/SqlClient/pull/1215)
+- Added new App Context switch to use OS enabled client protocols only. [#1168](https://github.com/dotnet/SqlClient/pull/1168) [Read more](#app-context-switch-for-using-system-default-protocols)
+- Added `PoolBlockingPeriod` connection property support in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181)
+- Added support for `SqlDataReader.GetColumnSchema()` in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181)
+- Added PropertyGrid support with component model annotations to `SqlConnectionStringBuilder` properties for .NET Core. [#1152](https://github.com/dotnet/SqlClient/pull/1152)
+
+### Fixed
+- Fixed issue with connectivity when TLS 1.3 is enabled on client and server. [#1168](https://github.com/dotnet/SqlClient/pull/1168)
+- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1210](https://github.com/dotnet/SqlClient/pull/1210) [Read more](#ensure-connections-fail-when-encryption-is-required)
+- Fixed issue where connection goes to unusable state. [#1128](https://github.com/dotnet/SqlClient/pull/1128)
+- Fixed recursive calls to `RetryLogicProvider` when calling `SqlCommand.ExecuteScalarAsync`. [#1220](https://github.com/dotnet/SqlClient/pull/1220)
+- Fixed async deadlock scenarios in web contexts with configurable retry logic provider. [#1220](https://github.com/dotnet/SqlClient/pull/1220)
+- Fixed `EntryPointNotFoundException` in `InOutOfProcHelper` constructor. [#1120](https://github.com/dotnet/SqlClient/pull/1120)
+- Fixed async thread blocking issues on `SqlConnection.Open()` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213)
+- Fixed driver behavior for Always Encrypted with secure enclaves to not fail when no user parameters have been provided. [#1115](https://github.com/dotnet/SqlClient/pull/1115)
+- Fixed bug with `LegacyRowVersionNullBehavior` App Context switch. [#1182](https://github.com/dotnet/SqlClient/pull/1182)
+- Fixed issues in Strings.resx file containing error messages. [#1136](https://github.com/dotnet/SqlClient/pull/1136) [#1178](https://github.com/dotnet/SqlClient/pull/1178)
+
+### Changed
+- Updated error code to match with Windows when certificate validation fails in non-Windows client environments. [#1130](https://github.com/dotnet/SqlClient/pull/1130)
+- Removed designer attributes from `SqlCommand` and `SqlDataAdapter`. [#1132](https://github.com/dotnet/SqlClient/pull/1132)
+- Updated configurable retry logic default retriable error list. [#1125](https://github.com/dotnet/SqlClient/pull/1125)
+- Improved performance by changing `SqlParameter` bool fields to flags. [#1064](https://github.com/dotnet/SqlClient/pull/1064)
+- Improved performance by implementing static delegates. [#1060](https://github.com/dotnet/SqlClient/pull/1060)
+- Optimized async method allocations in .NET Framework by porting changes from .NET Core. [#1084](https://github.com/dotnet/SqlClient/pull/1084)
+- Various code improvements [#902](https://github.com/dotnet/SqlClient/pull/902) [#925](https://github.com/dotnet/SqlClient/pull/925) [#933](https://github.com/dotnet/SqlClient/pull/933) [#934](https://github.com/dotnet/SqlClient/pull/934) [#1024](https://github.com/dotnet/SqlClient/pull/1024) [#1057](https://github.com/dotnet/SqlClient/pull/1057) [#1122](https://github.com/dotnet/SqlClient/pull/1122) [#1133](https://github.com/dotnet/SqlClient/pull/1133) [#1134](https://github.com/dotnet/SqlClient/pull/1134) [#1141](https://github.com/dotnet/SqlClient/pull/1141) [#1187](https://github.com/dotnet/SqlClient/pull/1187) [#1188](https://github.com/dotnet/SqlClient/pull/1188) [#1223](https://github.com/dotnet/SqlClient/pull/1223) [#1225](https://github.com/dotnet/SqlClient/pull/1225) [#1226](https://github.com/dotnet/SqlClient/pull/1226)
+
+## New features over stable release v3.0
+
+### Encrypt default value set to true
+The default value of the `Encrypt` connection setting has been changed from `false` to `true`. With the growing use of cloud databases and the need to ensure those connections are secure, it's time for this backwards-compatibility-breaking change.
+
+### Ensure connections fail when encryption is required
+In scenarios where client encryption libraries were disabled or unavailable, it was possible for unencrypted connections to be made when Encrypt was set to true or the server required encryption.
+
+### App Context Switch for using System default protocols
+TLS 1.3 is not supported by the driver; therefore, it has been removed from the supported protocols list by default. Users can switch back to forcing use of Operating System's client protocols, by enabling the App Context switch below:
+
+ `Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols`
+
+### Enable optimized parameter binding
+Microsoft.Data.SqlClient introduces new `SqlCommand` API, `EnableOptimizedParameterBinding` to improve performance of queries with large number of parameters. This property is disabled by default. When set to `true`, parameter names will not be sent to the SQL server when the command is executed.
+
+```cs
+public class SqlCommand
+{
+ public bool EnableOptimizedParameterBinding { get; set; }
+}
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.0-preview1.21232.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0-preview1.21232.1
+- Microsoft.Win32.Registry 5.0.0
+- System.Security.Principal.Windows 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Runtime.Caching 5.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0-preview1.21232.1
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Memory 4.5.4
+- System.Security.Principal.Windows 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.Caching 5.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Runtime.Loader 4.3.0
diff --git a/release-notes/4.0/4.0.0-preview2.md b/release-notes/4.0/4.0.0-preview2.md
new file mode 100644
index 0000000000..db321cc79f
--- /dev/null
+++ b/release-notes/4.0/4.0.0-preview2.md
@@ -0,0 +1,100 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.0.0-preview2.21264.2 released 21 September 2021
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v4.0.0-preview1
+
+- Removed `Configurable Retry Logic` safety switch. [#1254](https://github.com/dotnet/SqlClient/pull/1254) [Read more](#remove-configurable-retry-logic-safety-switch)
+
+### Added
+
+- Added support for `SqlFileStream` on Windows using .NET Standard 2.0 and above. [#1240](https://github.com/dotnet/SqlClient/pull/1240)
+- Added support for **localdb** `shared instance` using managed SNI. [#1237](https://github.com/dotnet/SqlClient/pull/1237) [Read more](#sqllocaldb-shared-instance-support)
+
+### Fixed
+
+- Fixed `.NET decimal` conversion from `SqlDecimal`. [#1179](https://github.com/dotnet/SqlClient/pull/1179)
+- Fixed `Event Source` changes on **TryBeginExecuteEvent** and **WriteEndExecuteEvent** to address the failure on other MS products such as OpenTelemetry and Application Insight. [#1258](https://github.com/dotnet/SqlClient/pull/1258)
+- Fixed command's async cancellation. [#956](https://github.com/dotnet/SqlClient/pull/956)
+- Fixed deadlock in transaction using .NET Framework. [#1242](https://github.com/dotnet/SqlClient/pull/1242)
+- Fixed unknown transaction state issues when prompting delegated transaction. [1216](https://github.com/dotnet/SqlClient/pull/1216)
+
+### Changed
+
+- Various code improvements [#1155](https://github.com/dotnet/SqlClient/pull/1155) [#1236](https://github.com/dotnet/SqlClient/pull/1236) [#1251](https://github.com/dotnet/SqlClient/pull/1251) [#1266](https://github.com/dotnet/SqlClient/pull/1266)
+
+### Remove configurable retry logic safety switch
+
+The App Context switch "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" will no longer be required to use the configurable retry logic feature. The feature is now supported in production. The default behavior of the feature will continue to be a non-retry policy, which will need to be overridden by client applications to enable retries.
+
+### SqlLocalDb shared instance support
+
+SqlLocalDb shared instances are now supported when using Managed SNI.
+
+- Possible scenarios:
+ - `(localdb)\.` (connects to default instance of SqlLocalDb)
+ - `(localdb)\`
+ - `(localdb)\.\` (*newly added support)
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 2.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.0-preview1.21232.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0-preview1.21232.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0-preview1.21232.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/4.0/4.0.0-preview3.md b/release-notes/4.0/4.0.0-preview3.md
new file mode 100644
index 0000000000..005ae6db0c
--- /dev/null
+++ b/release-notes/4.0/4.0.0-preview3.md
@@ -0,0 +1,118 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.0.0-preview3.21293.2 released 20 October 2021
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v4.0.0-preview2
+
+- Dropped support for .NET Core 2.1 [#1272](https://github.com/dotnet/SqlClient/pull/1272)
+- [.NET Framework] Exception will not be thrown if a User ID is provided in the connection string when using `Active Directory Integrated` authentication [#1359](https://github.com/dotnet/SqlClient/pull/1359)
+
+### Added
+
+- Add `GetFieldValueAsync` and `GetFieldValue` support for `XmlReader`, `TextReader`, `Stream` [#1019](https://github.com/dotnet/SqlClient/pull/1019). [Read more](#getfieldvalueasynct-and-getfieldvaluet-support-for-xmlreader-textreader-stream-types)
+
+### Fixed
+
+- Fixed `FormatException` when opening a connection with event tracing enabled [#1291](https://github.com/dotnet/SqlClient/pull/1291)
+- Fixed improper initialization of `ActiveDirectoryAuthenticationProvider` [#1328](https://github.com/dotnet/SqlClient/pull/1328)
+- Fixed `MissingMethodException` when accessing `SqlAuthenticationParameters.ConnectionTimeout` [#1336](https://github.com/dotnet/SqlClient/pull/1336)
+- Fixed data corruption issues by reverting changes to async cancellations [#1352](https://github.com/dotnet/SqlClient/pull/1352)
+- Fixed performance degradation by reverting changes to MARS state machine [#1357](https://github.com/dotnet/SqlClient/pull/1357)
+- Fixed bug where environment variables are ignored when using `Active Directory Default` authentication [#1360](https://github.com/dotnet/SqlClient/pull/1360)
+
+### Changed
+
+- Removed attributes for classes used in Microsoft.VSDesigner due to lack of support for Microsoft.Data.SqlClient [#1296](https://github.com/dotnet/SqlClient/pull/1296)
+- Disable encryption when connecting to SQL LocalDB [#1312](https://github.com/dotnet/SqlClient/pull/1312)
+- Various code health and performance improvements. See [milestone](https://github.com/dotnet/SqlClient/milestone/31?closed=1) for more info.
+
+## New features over preview release v4.0.0-preview2
+
+### `GetFieldValueAsync` and `GetFieldValue` support for `XmlReader`, `TextReader`, `Stream` types
+
+`XmlReader`, `TextReader`, `Stream` types are now supported when using `GetFieldValueAsync` and `GetFieldValue`.
+
+Example usage:
+
+```cs
+using (SqlConnection connection = new SqlConnection(connectionString))
+{
+ using (SqlCommand command = new SqlCommand(query, connection))
+ {
+ connection.Open();
+ using (SqlDataReader reader = await command.ExecuteReaderAsync())
+ {
+ if (await reader.ReadAsync())
+ {
+ using (Stream stream = await reader.GetFieldValueAsync(1))
+ {
+ // Continue to read from stream
+ }
+ }
+ }
+ }
+}
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.0-preview1.21232.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0-preview1.21232.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0-preview1.21232.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/4.0/4.0.0.md b/release-notes/4.0/4.0.0.md
new file mode 100644
index 0000000000..6059c27983
--- /dev/null
+++ b/release-notes/4.0/4.0.0.md
@@ -0,0 +1,196 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.0.0 released 18 November 2021
+
+This update brings the below changes over the previous preview release:
+
+### Added
+
+- Added missing `SqlClientLogger` class to .NET Core refs and missing `SqlClientLogger.LogWarning` method in .NET Framework refs [#1392](https://github.com/dotnet/SqlClient/pull/1392)
+
+### Changed
+
+- Avoid throwing unnecessary exception when an invalid `SqlNotificationInfo` value is received from SQL Server [#1378](https://github.com/dotnet/SqlClient/pull/1378)
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.0` [#1391](https://github.com/dotnet/SqlClient/pull/1391)
+
+## Summary of changes in 4.0
+
+All changes in Microsoft.Data.SqlClient v4.0 over v3.0:
+
+### New Additions
+
+- Added `SqlCommand.EnableOptimizedParameterBinding` property that when enabled increases performance for commands with very large numbers of parameters. [#1041](https://github.com/dotnet/SqlClient/pull/1041) [Read more](#enable-optimized-parameter-binding)
+- Included `42108` and `42109` error codes to retriable transient errors list. [#1215](https://github.com/dotnet/SqlClient/pull/1215)
+- Added new App Context switch to use OS enabled client protocols only. [#1168](https://github.com/dotnet/SqlClient/pull/1168). [Read more](#app-context-switch-for-using-system-default-protocols)
+- Added `PoolBlockingPeriod` connection property support in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181)
+- Added support for `SqlDataReader.GetColumnSchema()` in .NET Standard. [#1181](https://github.com/dotnet/SqlClient/pull/1181)
+- Added PropertyGrid support with component model annotations to `SqlConnectionStringBuilder` properties for .NET Core. [#1152](https://github.com/dotnet/SqlClient/pull/1152)
+- Added support for `SqlFileStream` on Windows using .NET Standard 2.0 and above. [#1240](https://github.com/dotnet/SqlClient/pull/1240)
+- Added support for **localdb** `shared instance` using managed SNI. [#1237](https://github.com/dotnet/SqlClient/pull/1237). [Read more](#sqllocaldb-shared-instance-support)
+- Added `GetFieldValueAsync` and `GetFieldValue` support for `XmlReader`, `TextReader`, `Stream` [#1019](https://github.com/dotnet/SqlClient/pull/1019). [Read more](#getfieldvalueasynct-and-getfieldvaluet-support-for-xmlreader-textreader-stream-types)
+- Added missing `SqlClientLogger` class to .NET Core refs and missing 'SqlClientLogger.LogWarning' method in .NET Framework refs [#1392](https://github.com/dotnet/SqlClient/pull/1392)
+
+### Bug Fixes
+
+- Fixed issue with connectivity when TLS 1.3 is enabled on client and server. [#1168](https://github.com/dotnet/SqlClient/pull/1168)
+- Fixed issue with connection encryption to ensure connections fail when encryption is required. [#1210](https://github.com/dotnet/SqlClient/pull/1210) [Read more](#ensure-connections-fail-when-encryption-is-required)
+- Fixed issue where connection goes to unusable state. [#1128](https://github.com/dotnet/SqlClient/pull/1128)
+- Fixed recursive calls to `RetryLogicProvider` when calling `SqlCommand.ExecuteScalarAsync`. [#1220](https://github.com/dotnet/SqlClient/pull/1220)
+- Fixed async deadlock scenarios in web contexts with configurable retry logic provider. [#1220](https://github.com/dotnet/SqlClient/pull/1220)
+- Fixed `EntryPointNotFoundException` in `InOutOfProcHelper` constructor. [#1120](https://github.com/dotnet/SqlClient/pull/1120)
+- Fixed async thread blocking issues on `SqlConnection.Open()` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213)
+- Fixed driver behavior for Always Encrypted with secure enclaves to not fail when no user parameters have been provided. [#1115](https://github.com/dotnet/SqlClient/pull/1115)
+- Fixed bug with `LegacyRowVersionNullBehavior` App Context switch. [#1182](https://github.com/dotnet/SqlClient/pull/1182)
+- Fixed issues in Strings.resx file containing error messages. [#1136](https://github.com/dotnet/SqlClient/pull/1136) [#1178](https://github.com/dotnet/SqlClient/pull/1178)
+- Fixed `.NET decimal` conversion from `SqlDecimal`. [#1179](https://github.com/dotnet/SqlClient/pull/1179)
+- Fixed `Event Source` changes on **TryBeginExecuteEvent** and **WriteEndExecuteEvent** to address the failure on other MS products such as OpenTelemetry and Application Insight. [#1258](https://github.com/dotnet/SqlClient/pull/1258)
+- Fixed deadlock in transaction using .NET Framework. [#1242](https://github.com/dotnet/SqlClient/pull/1242)
+- Fixed unknown transaction state issues when prompting delegated transaction. [1216](https://github.com/dotnet/SqlClient/pull/1216)
+- Fixed `FormatException` when opening a connection with event tracing enabled [#1291](https://github.com/dotnet/SqlClient/pull/1291)
+- Fixed improper initialization of `ActiveDirectoryAuthenticationProvider` [#1328](https://github.com/dotnet/SqlClient/pull/1328)
+- Fixed `MissingMethodException` when accessing `SqlAuthenticationParameters.ConnectionTimeout` [#1336](https://github.com/dotnet/SqlClient/pull/1336)
+- Fixed bug where environment variables are ignored when using `Active Directory Default` authentication [#1360](https://github.com/dotnet/SqlClient/pull/1360)
+
+### Improvements and Changes
+
+- Updated error code to match with Windows when certificate validation fails in non-Windows client environments. [#1130](https://github.com/dotnet/SqlClient/pull/1130)
+- Removed designer attributes from `SqlCommand` and `SqlDataAdapter`. [#1132](https://github.com/dotnet/SqlClient/pull/1132)
+- Updated configurable retry logic default retriable error list. [#1125](https://github.com/dotnet/SqlClient/pull/1125)
+- Improved performance by changing `SqlParameter` bool fields to flags. [#1064](https://github.com/dotnet/SqlClient/pull/1064)
+- Improved performance by implementing static delegates. [#1060](https://github.com/dotnet/SqlClient/pull/1060)
+- Optimized async method allocations in .NET Framework by porting changes from .NET Core. [#1084](https://github.com/dotnet/SqlClient/pull/1084)
+- Various code improvements [#902](https://github.com/dotnet/SqlClient/pull/902) [#925](https://github.com/dotnet/SqlClient/pull/925) [#933](https://github.com/dotnet/SqlClient/pull/933) [#934](https://github.com/dotnet/SqlClient/pull/934) [#1024](https://github.com/dotnet/SqlClient/pull/1024) [#1057](https://github.com/dotnet/SqlClient/pull/1057) [#1122](https://github.com/dotnet/SqlClient/pull/1122) [#1133](https://github.com/dotnet/SqlClient/pull/1133) [#1134](https://github.com/dotnet/SqlClient/pull/1134) [#1141](https://github.com/dotnet/SqlClient/pull/1141) [#1155](https://github.com/dotnet/SqlClient/pull/1155) [#1187](https://github.com/dotnet/SqlClient/pull/1187) [#1188](https://github.com/dotnet/SqlClient/pull/1188) [#1223](https://github.com/dotnet/SqlClient/pull/1223) [#1225](https://github.com/dotnet/SqlClient/pull/1225) [#1226](https://github.com/dotnet/SqlClient/pull/1226) [#1236](https://github.com/dotnet/SqlClient/pull/1236) [#1251](https://github.com/dotnet/SqlClient/pull/1251) [#1266](https://github.com/dotnet/SqlClient/pull/1266)
+- Removed attributes for classes used in Microsoft.VSDesigner due to lack of support for Microsoft.Data.SqlClient [#1296](https://github.com/dotnet/SqlClient/pull/1296)
+- Disable encryption when connecting to SQL LocalDB [#1312](https://github.com/dotnet/SqlClient/pull/1312)
+- Avoid throwing unnecessary exception when an invalid SqlNotificationInfo value is received from SQL Server [#1378](https://github.com/dotnet/SqlClient/pull/1378)
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.0` [#1391](https://github.com/dotnet/SqlClient/pull/1391)
+- Various code health and performance improvements. See [milestone](https://github.com/dotnet/SqlClient/milestone/31?closed=1) for more info.
+
+### Breaking Changes
+- Changed `Encrypt` connection string property to be `true` by default. [#1210](https://github.com/dotnet/SqlClient/pull/1210) [Read more](#encrypt-default-value-set-to-true)
+- The driver now throws `SqlException` replacing `AggregateException` for active directory authentication modes. [#1213](https://github.com/dotnet/SqlClient/pull/1213)
+- Dropped obsolete `Asynchronous Processing` connection property from .NET Framework. [#1148](https://github.com/dotnet/SqlClient/pull/1148)
+- Removed `Configurable Retry Logic` safety switch. [#1254](https://github.com/dotnet/SqlClient/pull/1254) [Read more](#remove-configurable-retry-logic-safety-switch)
+- Dropped support for .NET Core 2.1 [#1272](https://github.com/dotnet/SqlClient/pull/1272)
+- [.NET Framework] Exception will not be thrown if a User ID is provided in the connection string when using `Active Directory Integrated` authentication [#1359](https://github.com/dotnet/SqlClient/pull/1359)
+
+### Encrypt default value set to true
+The default value of the `Encrypt` connection setting has been changed from `false` to `true`. With the growing use of cloud databases and the need to ensure those connections are secure, it's time for this backwards-compatibility-breaking change.
+
+### Ensure connections fail when encryption is required
+In scenarios where client encryption libraries were disabled or unavailable, it was possible for unencrypted connections to be made when Encrypt was set to true or the server required encryption.
+
+### App Context Switch for using System default protocols
+TLS 1.3 is not supported by the driver; therefore, it has been removed from the supported protocols list by default. Users can switch back to forcing use of the Operating System's client protocols, by enabling the App Context switch below:
+
+ `Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols`
+
+### Enable optimized parameter binding
+Microsoft.Data.SqlClient introduces a new `SqlCommand` API, `EnableOptimizedParameterBinding` to improve performance of queries with a large number of parameters. This property is disabled by default. When set to `true`, parameter names will not be sent to the SQL server when the command is executed.
+
+```cs
+public class SqlCommand
+{
+ public bool EnableOptimizedParameterBinding { get; set; }
+}
+```
+
+### Remove configurable retry logic safety switch
+
+The App Context switch "Switch.Microsoft.Data.SqlClient.EnableRetryLogic" will no longer be required to use the configurable retry logic feature. The feature is now supported in production. The default behavior of the feature will continue to be a non-retry policy, which will need to be overridden by client applications to enable retries.
+
+### SqlLocalDb shared instance support
+
+SqlLocalDb shared instances are now supported when using Managed SNI.
+
+- Possible scenarios:
+ - `(localdb)\.` (connects to default instance of SqlLocalDb)
+ - `(localdb)\`
+ - `(localdb)\.\` (*newly added support)
+
+### `GetFieldValueAsync` and `GetFieldValue` support for `XmlReader`, `TextReader`, `Stream` types
+
+`XmlReader`, `TextReader`, `Stream` types are now supported when using `GetFieldValueAsync` and `GetFieldValue`.
+
+Example usage:
+
+```cs
+using (SqlConnection connection = new SqlConnection(connectionString))
+{
+ using (SqlCommand command = new SqlCommand(query, connection))
+ {
+ connection.Open();
+ using (SqlDataReader reader = await command.ExecuteReaderAsync())
+ {
+ if (await reader.ReadAsync())
+ {
+ using (Stream stream = await reader.GetFieldValueAsync(1))
+ {
+ // Continue to read from stream
+ }
+ }
+ }
+ }
+}
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/4.0/4.0.1.md b/release-notes/4.0/4.0.1.md
new file mode 100644
index 0000000000..7e43a9bcc8
--- /dev/null
+++ b/release-notes/4.0/4.0.1.md
@@ -0,0 +1,83 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.0.1 released 17 January 2022
+
+This update brings the below changes over the previous preview release:
+
+### Added
+
+- Added AppContext switch `SuppressInsecureTLSWarning` to allow suppression of TLS security warning when using `Encrypt=false` in the connection string. [#1457](https://github.com/dotnet/SqlClient/pull/1457) [Read more](#suppress-tls-security-warnings)
+
+### Fixed
+
+- Fixed Kerberos authentication failure when using .NET 6. [#1411](https://github.com/dotnet/SqlClient/pull/1411)
+- Fixed connection failure when using `SqlLocalDB` instance pipe name. [#1433](https://github.com/dotnet/SqlClient/pull/1433)
+- Fixed a failure when executing concurrent queries requiring enclaves. [#1451](https://github.com/dotnet/SqlClient/pull/1451)
+- Updated obsolete API calls targeting .NET 6. [#1401](https://github.com/dotnet/SqlClient/pull/1401)
+
+### Suppress TLS security warnings
+
+When connecting to a SQL Server, if a protocol lower than TLS 1.2 is negotiated, a security warning is printed out to the console. This warning can be suppressed by enabling the following `AppContext` switch on the application startup while `Encrypt` is set to `false` on connection string.
+
+`Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning`
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
\ No newline at end of file
diff --git a/release-notes/4.0/4.0.2.md b/release-notes/4.0/4.0.2.md
new file mode 100644
index 0000000000..96c485a613
--- /dev/null
+++ b/release-notes/4.0/4.0.2.md
@@ -0,0 +1,80 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.0.2 released 13 September 2022
+
+This update brings the below changes over the previous preview release:
+
+### Fixed
+
+- Fixed connection failure by not requiring Certificate Revocation List (CRL) check during authentication. [#1718](https://github.com/dotnet/SqlClient/pull/1718)
+- Parallelize SSRP requests on Linux and macOS when MultiSubNetFailover is specified. [#1720](https://github.com/dotnet/SqlClient/pull/1720), [#1747](https://github.com/dotnet/SqlClient/pull/1747)
+- Added CommandText length validation when using stored procedure command types. [#1721](https://github.com/dotnet/SqlClient/pull/1721)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1722](https://github.com/dotnet/SqlClient/pull/1722)
+- Fixed null SqlBinary as rowversion. [#1724](https://github.com/dotnet/SqlClient/pull/1724)
+- Fixed table's collation overriding with default UTF8 collation. [#1750](https://github.com/dotnet/SqlClient/pull/1750)
+
+## Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.1` [#1754](https://github.com/dotnet/SqlClient/pull/1754), which includes the fix for AppDomain crash introducing in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418)
+- Various code improvements: [#1723](https://github.com/dotnet/SqlClient/pull/1723)
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/4.0/4.0.md b/release-notes/4.0/4.0.md
new file mode 100644
index 0000000000..8d0ffeceb8
--- /dev/null
+++ b/release-notes/4.0/4.0.md
@@ -0,0 +1,17 @@
+# Microsoft.Data.SqlClient 4.0 Releases
+
+The following Microsoft.Data.SqlClient 4.0 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/09/13 | 4.0.2 | [release notes](4.0.2.md) |
+| 2022/01/17 | 4.0.1 | [release notes](4.0.1.md) |
+| 2021/11/18 | 4.0.0 | [release notes](4.0.0.md) |
+
+The following Microsoft.Data.SqlClient 4.0 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2021/10/20 | 4.0.0-preview3.21293.2 | [release notes](4.0.0-preview3.md) |
+| 2021/09/21 | 4.0.0-preview2.21264.2 | [release notes](4.0.0-preview2.md) |
+| 2021/08/25 | 4.0.0-preview1.21237.2 | [release notes](4.0.0-preview1.md) |
diff --git a/release-notes/4.0/README.md b/release-notes/4.0/README.md
new file mode 100644
index 0000000000..8d0ffeceb8
--- /dev/null
+++ b/release-notes/4.0/README.md
@@ -0,0 +1,17 @@
+# Microsoft.Data.SqlClient 4.0 Releases
+
+The following Microsoft.Data.SqlClient 4.0 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/09/13 | 4.0.2 | [release notes](4.0.2.md) |
+| 2022/01/17 | 4.0.1 | [release notes](4.0.1.md) |
+| 2021/11/18 | 4.0.0 | [release notes](4.0.0.md) |
+
+The following Microsoft.Data.SqlClient 4.0 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2021/10/20 | 4.0.0-preview3.21293.2 | [release notes](4.0.0-preview3.md) |
+| 2021/09/21 | 4.0.0-preview2.21264.2 | [release notes](4.0.0-preview2.md) |
+| 2021/08/25 | 4.0.0-preview1.21237.2 | [release notes](4.0.0-preview1.md) |
diff --git a/release-notes/4.1/4.1.0.md b/release-notes/4.1/4.1.0.md
new file mode 100644
index 0000000000..c8fdd801da
--- /dev/null
+++ b/release-notes/4.1/4.1.0.md
@@ -0,0 +1,82 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.1.0 released 31 January 2022
+
+This update brings the below changes over the previous preview release:
+
+### Added
+
+- Added new Attestation Protocol `None` for `VBS` enclave types. This protocol will allow users to forgo enclave attestation for VBS enclaves. [#1419](https://github.com/dotnet/SqlClient/pull/1419) [#1425](https://github.com/dotnet/SqlClient/pull/1425) [Read more](#introduce-attestation-protocol-none)
+
+### Introduce Attestation Protocol None
+
+A new attestation protocol called `None` will be allowed in the connection string. This protocol will allow users to forgo enclave attestation for `VBS` enclaves. When this protocol is set, the enclave attestation URL property is optional.
+
+Connection string example:
+
+```cs
+//Attestation protocol NONE with no URL
+"Data Source = {server}; Initial Catalog = {db}; Column Encryption Setting = Enabled; Attestation Protocol = None;"
+
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.0
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
\ No newline at end of file
diff --git a/release-notes/4.1/4.1.1.md b/release-notes/4.1/4.1.1.md
new file mode 100644
index 0000000000..f6fbc70f19
--- /dev/null
+++ b/release-notes/4.1/4.1.1.md
@@ -0,0 +1,80 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 4.1.1 released 13 September 2022
+
+This update brings the below changes over the previous preview release:
+
+### Fixed
+
+- Fixed connection failure by not requiring Certificate Revocation List (CRL) check during authentication. [#1706](https://github.com/dotnet/SqlClient/pull/1706)
+- Parallelize SSRP requests on Linux and macOS when MultiSubNetFailover is specified. [#1708](https://github.com/dotnet/SqlClient/pull/1708), [#1746](https://github.com/dotnet/SqlClient/pull/1746)
+- Added CommandText length validation when using stored procedure command types. [#1709](https://github.com/dotnet/SqlClient/pull/1709)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1710](https://github.com/dotnet/SqlClient/pull/1710)
+- Fixed null SqlBinary as rowversion. [#1712](https://github.com/dotnet/SqlClient/pull/1712)
+- Fixed table's collation overriding with default UTF8 collation. [#1749](https://github.com/dotnet/SqlClient/pull/1749)
+
+## Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v4.0.1` [#1755](https://github.com/dotnet/SqlClient/pull/1755), which includes the fix for AppDomain crash introducing in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418)
+- Various code improvements: [#1711](https://github.com/dotnet/SqlClient/pull/1711)
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 4.0.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 4.0.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
\ No newline at end of file
diff --git a/release-notes/4.1/4.1.md b/release-notes/4.1/4.1.md
new file mode 100644
index 0000000000..a310caa5f7
--- /dev/null
+++ b/release-notes/4.1/4.1.md
@@ -0,0 +1,8 @@
+# Microsoft.Data.SqlClient 4.1 Releases
+
+The following Microsoft.Data.SqlClient 4.1 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/09/13 | 4.1.1 | [release notes](4.1.1.md) |
+| 2022/01/31 | 4.1.0 | [release notes](4.1.0.md) |
diff --git a/release-notes/4.1/README.md b/release-notes/4.1/README.md
new file mode 100644
index 0000000000..a310caa5f7
--- /dev/null
+++ b/release-notes/4.1/README.md
@@ -0,0 +1,8 @@
+# Microsoft.Data.SqlClient 4.1 Releases
+
+The following Microsoft.Data.SqlClient 4.1 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/09/13 | 4.1.1 | [release notes](4.1.1.md) |
+| 2022/01/31 | 4.1.0 | [release notes](4.1.0.md) |
diff --git a/release-notes/5.0/5.0.0-preview1.md b/release-notes/5.0/5.0.0-preview1.md
new file mode 100644
index 0000000000..55faad3c70
--- /dev/null
+++ b/release-notes/5.0/5.0.0-preview1.md
@@ -0,0 +1,136 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.0.0-preview1.22069.1 released 9 March 2022
+
+This update brings the below changes over the previous release:
+
+### Added
+
+- Added SqlDataSourceEnumerator. [#1430](https://github.com/dotnet/SqlClient/pull/1430), [Read more](#sql-data-source-enumerator-support)
+- Added new attestation protocol `None` option to forgo enclave attestation when using VBS enclaves. [#1425](https://github.com/dotnet/SqlClient/pull/1425) and [#1419](https://github.com/dotnet/SqlClient/pull/1419), [Read more](#new-attestation-protocol-none)
+- Added a new AppContext switch to suppress insecure TLS warnings. [#1457](https://github.com/dotnet/SqlClient/pull/1457), [Read more](#suppress-insecure-tls-warnings)
+
+### Fixed
+
+- Fixed all documentation paths to Unix format path. [#1442](https://github.com/dotnet/SqlClient/pull/1442)
+- Fixed thread safety issue for `GetEnclaveProvider` by converting dictionary to concurrent dictionary. [#1451](https://github.com/dotnet/SqlClient/pull/1451)
+
+### Changed
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `v5.0.0-preview1.22062.1`. [#1537](https://github.com/dotnet/SqlClient/pull/1537)
+- Modernized style in ValueUtilSmi. [#1351](https://github.com/dotnet/SqlClient/pull/1351)
+- Changed SQL server codenames to version names. [#1439](https://github.com/dotnet/SqlClient/pull/1439)
+- Prevented subtype generation in project files. [#1452](https://github.com/dotnet/SqlClient/pull/1452)
+- Changed `Array.Copy` to `Buffer.BlockCopy` for byte arrays. [#1366](https://github.com/dotnet/SqlClient/pull/1366)
+- Changed files in csproj to be alphabetically sorted in netfx and netcore. [#1364](https://github.com/dotnet/SqlClient/pull/1364)
+- Sqlstream, SqlInternalTransaction and MetaDataUtilsSmi are moved to shared folder. [#1337](https://github.com/dotnet/SqlClient/pull/1337), [#1346](https://github.com/dotnet/SqlClient/pull/1346) and [#1339](https://github.com/dotnet/SqlClient/pull/1339)
+- Various code improvements: [#1197](https://github.com/dotnet/SqlClient/pull/1197), [#1313](https://github.com/dotnet/SqlClient/pull/1313),[#1330](https://github.com/dotnet/SqlClient/pull/1330),[#1366](https://github.com/dotnet/SqlClient/pull/1366), [#1435](https://github.com/dotnet/SqlClient/pull/1435),[#1478](https://github.com/dotnet/SqlClient/pull/1478)
+
+### SQL Data Source Enumerator support
+Provides a mechanism for enumerating all available instances of SQL Server within the local network.
+```cs
+using Microsoft.Data.Sql;
+
+static void Main()
+ {
+ // Retrieve the enumerator instance and then the data.
+ SqlDataSourceEnumerator instance =
+ SqlDataSourceEnumerator.Instance;
+ System.Data.DataTable table = instance.GetDataSources();
+
+ // Display the contents of the table.
+ DisplayData(table);
+
+ Console.WriteLine("Press any key to continue.");
+ Console.ReadKey();
+ }
+
+ private static void DisplayData(System.Data.DataTable table)
+ {
+ foreach (System.Data.DataRow row in table.Rows)
+ {
+ foreach (System.Data.DataColumn col in table.Columns)
+ {
+ Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
+ }
+ Console.WriteLine("============================");
+ }
+ }
+```
+
+### New Attestation protocol `None`
+ new attestation protocol called `None` will be allowed in the connection string. This protocol will allow users to forgo enclave attestation for `VBS` enclaves. When this protocol is set, the enclave attestation URL property is optional.
+
+Connection string example:
+
+```cs
+//Attestation protocol NONE with no URL
+"Data Source = {server}; Initial Catalog = {db}; Column Encryption Setting = Enabled; Attestation Protocol = None;"
+
+```
+
+### Suppress insecure TLS warnings
+A security warning is ouptput on the console if the TLS version less than 1.2 is used to negotiate with the server. This warning could be suppressed on SQL connection while `Encrypt = false` by enabling the following AppContext switch on the application startup:
+```cs
+Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 5.0.0.preview1.22062.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0.preview1.22062.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0.preview1.22062.1
+- Azure.Identity 1.3.0
+- Microsoft.Identity.Client 4.22.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
\ No newline at end of file
diff --git a/release-notes/5.0/5.0.0-preview2.md b/release-notes/5.0/5.0.0-preview2.md
new file mode 100644
index 0000000000..16158a05fb
--- /dev/null
+++ b/release-notes/5.0/5.0.0-preview2.md
@@ -0,0 +1,82 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.0.0-preview2.22096.2 released 6 April 2022
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v5.0.0-preview1
+
+- Dropped support for .NET Framework 4.6.1 [#1574](https://github.com/dotnet/SqlClient/pull/1574)
+
+### Fixed
+
+- Fixed connection failure by skipping Certificate Revocation List (CRL) check during authentication [#1559](https://github.com/dotnet/SqlClient/pull/1559)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.0.0-preview2.22084.1`. [#1563](https://github.com/dotnet/SqlClient/pull/1563)
+- Updated `Azure.Identity` version to `1.5.0` and `Microsoft.Identity.Client` version to `4.30.1` [#1462](https://github.com/dotnet/SqlClient/pull/1462)
+- Replaced AlwaysEncryptedAttestationException with SqlException [#1515](https://github.com/dotnet/SqlClient/pull/1515)
+- Improved error message when adding wrong type to SqlParameterCollection [#1547](https://github.com/dotnet/SqlClient/pull/1547)
+- Code health improvements [#1343](https://github.com/dotnet/SqlClient/pull/1343) [#1370](https://github.com/dotnet/SqlClient/pull/1370) [#1371](https://github.com/dotnet/SqlClient/pull/1371) [#1438](https://github.com/dotnet/SqlClient/pull/1438) [#1483](https://github.com/dotnet/SqlClient/pull/1483)
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 5.0.0-preview2.22084.1
+- Azure.Identity 1.5.0
+- Microsoft.Identity.Client 4.30.1
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encodings.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0-preview2.22084.1
+- Azure.Identity 1.5.0
+- Microsoft.Identity.Client 4.30.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0-preview2.22084.1
+- Azure.Identity 1.5.0
+- Microsoft.Identity.Client 4.30.1
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
\ No newline at end of file
diff --git a/release-notes/5.0/5.0.0-preview3.md b/release-notes/5.0/5.0.0-preview3.md
new file mode 100644
index 0000000000..19819018bd
--- /dev/null
+++ b/release-notes/5.0/5.0.0-preview3.md
@@ -0,0 +1,128 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.0.0-preview3 released 16 June 2022
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v5.0.0-preview2
+
+- Added a dependency on the [Microsoft.SqlServer.Server](https://github.com/dotnet/SqlClient/tree/main/src/Microsoft.SqlServer.Server) package. This new dependency may cause namespace conflicts if your application references that namespace and still has package references (direct or indirect) to System.Data.SqlClient from .NET Core.
+- Dropped classes from the `Microsoft.Data.SqlClient.Server` namespace and replaced them with supported types from the [Microsoft.SqlServer.Server](https://github.com/dotnet/SqlClient/tree/main/src/Microsoft.SqlServer.Server) package.[#1585](https://github.com/dotnet/SqlClient/pull/1585) The affected classes and enums are:
+ - Microsoft.Data.SqlClient.Server.IBinarySerialize -> Microsoft.SqlServer.Server.IBinarySerialize
+ - Microsoft.Data.SqlClient.Server.InvalidUdtException -> Microsoft.SqlServer.Server.InvalidUdtException
+ - Microsoft.Data.SqlClient.Server.SqlFacetAttribute -> Microsoft.SqlServer.Server.SqlFacetAttribute
+ - Microsoft.Data.SqlClient.Server.SqlFunctionAttribute -> Microsoft.SqlServer.Server.SqlFunctionAttribute
+ - Microsoft.Data.SqlClient.Server.SqlMethodAttribute -> Microsoft.SqlServer.Server.SqlMethodAttribute
+ - Microsoft.Data.SqlClient.Server.SqlUserDefinedAggregateAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
+ - Microsoft.Data.SqlClient.Server.SqlUserDefinedTypeAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
+ - (enum) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
+ - (enum) Microsoft.Data.SqlClient.Server.Format -> Microsoft.SqlServer.Server.Format
+ - (enum) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind
+
+### Added
+
+- Added support for `TDS 8`. To use TDS 8, users should specify Encrypt=Strict in the connection string. [#1608](https://github.com/dotnet/SqlClient/pull/1608) [Read more](#tds-8-enhanced-security)
+- Added support for specifying Server SPN and Failover Server SPN on the connection. [#1607](https://github.com/dotnet/SqlClient/pull/1607) [Read more](#server-spn)
+- Added support for aliases when targeting .NET Core on Windows. [#1588](https://github.com/dotnet/SqlClient/pull/1588) [Read more](#support-for-aliases)
+
+### Fixed
+
+- Fixed naming, order, and formatting for `SqlDiagnosticsListener` on .NET Core and .NET. [#1637] (https://github.com/dotnet/SqlClient/pull/1637)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1625] (https://github.com/dotnet/SqlClient/pull/1625)
+- Added CommandText length validation when using stored procedure command types. [#1484](https://github.com/dotnet/SqlClient/pull/1484)
+- Fixed `GetSchema("StructuredTypeMembers")` to return correct schema information. [#1500] (https://github.com/dotnet/SqlClient/pull/1500), [#1639](https://github.com/dotnet/SqlClient/pull/1639)
+- Fixed NullReferenceException when using `SqlDependency.Start` against an Azure SQL Database.[#1294] (https://github.com/dotnet/SqlClient/pull/1294)
+- Send the correct retained transaction descriptor in the MARS TDS Header when there is no current transaction on .NET 5+ and .NET Core. [#1624] (https://github.com/dotnet/SqlClient/pull/1624)
+- Parallelize SSRP requests on Linux and macOS when MultiSubNetFailover is specified. [#1578] (https://github.com/dotnet/SqlClient/pull/1578)
+- Adjust the default ConnectRetryCount against Azure Synapse OnDemand endpoints [#1626] (https://github.com/dotnet/SqlClient/pull/1626)
+
+### Changed
+
+- Code health improvements [#1353](https://github.com/dotnet/SqlClient/pull/1353) [#1354](https://github.com/dotnet/SqlClient/pull/1354) [#1525](https://github.com/dotnet/SqlClient/pull/1525) [#1186](https://github.com/dotnet/SqlClient/pull/1186)
+- Update Azure Identity dependency from 1.5.0 to 1.6.0.[#1611](https://github.com/dotnet/SqlClient/pull/1611)
+- Improved Regex for SqlCommandSet [#1548] (https://github.com/dotnet/SqlClient/pull/1548)
+- Rework on `TdsParserStateObjectManaged` with nullable annotations. [#1555] (https://github.com/dotnet/SqlClient/pull/1555)
+
+### TDS 8 Enhanced Security
+
+To use TDS 8, specify Encrypt=Strict in the connection string. Strict mode disables TrustServerCertificate (always treated as False in Strict mode). HostNameInCertificate has been added to help some Strict mode scenarios. TDS 8 begins and continues all server communication inside a secure, encrypted TLS connection.
+
+New Encrypt values have been added to clarify connection encryption behavior. Encrypt=Mandatory is equavalent to Encrypt=True and encrypts connections during the TDS connection negotiation. Encrypt=Optional is equivalent to Encrypt=False and only encrypts the connection if the server tells the client that encryption is required during the TDS connection negotiation.
+
+HostNameInCertificate can be specified in the connection string when using aliases to connect with encryption to a server that has a server certificate with a different name or alternate subject name than the name used by the client to identify the server (DNS aliases, for example). Example usage: HostNameInCertificate=MyDnsAliasName
+
+### Server SPN
+
+When connecting in an environment that has unique domain/forest topography, the ServerSPN/Server SPN and FailoverServerSPN/Failover Server SPN connection string settings can be used to override the auto-generated server SPNs used in the library when authenticating with integrated authentication in a domain environment.
+
+### Support for Aliases
+
+Users can configure Aliases by using the SQL Server Configuration Manager. These are stored in the Windows registry and are already supported when targeting .NET Framework. This release brings support for aliases when targeting .NET or .NET Core on Windows.
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0-preview3.22165.1
+- Azure.Identity 1.6.0.0
+- Microsoft.Identity.Client 4.43.2.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0.0
+- System.Buffers 4.0.3.0
+- System.Configuration 4.0.0.0
+- System.Data 4.0.0.0
+- System.EnterpriseServices 4.0.0.0
+- System.IdentityModel.Tokens.Jwt 6.8.0.0
+- System.Runtime.Caching 4.0.0.0
+- System.Runtime.InteropServices.RuntimeInformation 4.0.2.0
+- System.Runtime.Serialization 4.0.0.0
+- System.Transactions 4.0.0.0
+- System.Xml 4.0.0.0
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0-preview3.22165.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.43.2
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0-preview3.22165.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.43.2
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.8.0
+- Microsoft.IdentityModel.JsonWebTokens 6.8.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+- System.Security.Permissions 5.0.0
+- NetStandard.Library 2.0.3
diff --git a/release-notes/5.0/5.0.0.md b/release-notes/5.0/5.0.0.md
new file mode 100644
index 0000000000..1bf0f071c5
--- /dev/null
+++ b/release-notes/5.0/5.0.0.md
@@ -0,0 +1,196 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.0.0 released 5 August 2022
+
+This update includes the following changes over the 4.1 release:
+
+### Breaking changes
+
+- As part of the [`TDS 8` feature](#tds-8-enhanced-security), the `SqlConnectionStringBuilder.Encrypt` property has changed from a `bool` to a `SqlConnectionEncryptOption`. `SqlConnectionEncryptOption` has implicit conversion rules to convert to/from a `bool` so that existing code remains backwards compatible, however this is a binary-breaking change and a recompile is required against this version.
+- Added a dependency on the [Microsoft.SqlServer.Server](https://github.com/dotnet/SqlClient/tree/main/src/Microsoft.SqlServer.Server) package. This new dependency may cause namespace conflicts if your application references that namespace and still has package references (direct or indirect) to System.Data.SqlClient from .NET Core.
+- Dropped classes from the `Microsoft.Data.SqlClient.Server` namespace and replaced them with supported types from the [Microsoft.SqlServer.Server](https://github.com/dotnet/SqlClient/tree/main/src/Microsoft.SqlServer.Server) package.[#1585](https://github.com/dotnet/SqlClient/pull/1585) The affected classes and enums are:
+ - Microsoft.Data.SqlClient.Server.IBinarySerialize -> Microsoft.SqlServer.Server.IBinarySerialize
+ - Microsoft.Data.SqlClient.Server.InvalidUdtException -> Microsoft.SqlServer.Server.InvalidUdtException
+ - Microsoft.Data.SqlClient.Server.SqlFacetAttribute -> Microsoft.SqlServer.Server.SqlFacetAttribute
+ - Microsoft.Data.SqlClient.Server.SqlFunctionAttribute -> Microsoft.SqlServer.Server.SqlFunctionAttribute
+ - Microsoft.Data.SqlClient.Server.SqlMethodAttribute -> Microsoft.SqlServer.Server.SqlMethodAttribute
+ - Microsoft.Data.SqlClient.Server.SqlUserDefinedAggregateAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
+ - Microsoft.Data.SqlClient.Server.SqlUserDefinedTypeAttribute -> Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
+ - (enum) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
+ - (enum) Microsoft.Data.SqlClient.Server.Format -> Microsoft.SqlServer.Server.Format
+ - (enum) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind
+- Dropped support for .NET Framework 4.6.1 [#1574](https://github.com/dotnet/SqlClient/pull/1574)
+
+
+### Added
+
+- Added support for `TDS 8`. To use TDS 8, users should specify Encrypt=Strict in the connection string. [#1608](https://github.com/dotnet/SqlClient/pull/1608) [Read more](#tds-8-enhanced-security)
+- Added `TDS 8` version for TDSLogin. [#1657](https://github.com/dotnet/SqlClient/pull/1657)
+- Added support for specifying Server SPN and Failover Server SPN on the connection. [#1607](https://github.com/dotnet/SqlClient/pull/1607) [Read more](#server-spn)
+- Added support for aliases when targeting .NET Core on Windows. [#1588](https://github.com/dotnet/SqlClient/pull/1588) [Read more](#support-for-aliases)
+- Added support for `SqlDataSourceEnumerator` on Windows. [#1430](https://github.com/dotnet/SqlClient/pull/1430), [Read more](#sql-data-source-enumerator-support)
+- Added new attestation protocol `None` option to forgo enclave attestation when using VBS enclaves. [#1425](https://github.com/dotnet/SqlClient/pull/1425) and [#1419](https://github.com/dotnet/SqlClient/pull/1419), [Read more](#new-attestation-protocol-none)
+- Added a new AppContext switch to suppress insecure TLS warnings. [#1457](https://github.com/dotnet/SqlClient/pull/1457), [Read more](#suppress-insecure-tls-warnings)
+
+### Fixed
+
+- Fixed null SqlBinary as rowversion. [#1688](https://github.com/dotnet/SqlClient/pull/1688)
+- Fixed **KeyNotFoundException** for the `FailoverPartner` key on SQL servers with availability group configured. [#1614](https://github.com/dotnet/SqlClient/pull/1614)
+- Fixed naming, order, and formatting for `SqlDiagnosticsListener` on .NET Core and .NET. [#1637](https://github.com/dotnet/SqlClient/pull/1637)
+- Fixed NullReferenceException during Azure Active Directory authentication. [#1625](https://github.com/dotnet/SqlClient/pull/1625)
+- Added CommandText length validation when using stored procedure command types. [#1484](https://github.com/dotnet/SqlClient/pull/1484)
+- Fixed `GetSchema("StructuredTypeMembers")` to return correct schema information. [#1500](https://github.com/dotnet/SqlClient/pull/1500), [#1639](https://github.com/dotnet/SqlClient/pull/1639)
+- Fixed **NullReferenceException** when using `SqlDependency.Start` against an Azure SQL Database. [#1294](https://github.com/dotnet/SqlClient/pull/1294)
+- Fixed transaction descriptor in the MARS TDS Header when there is no current transaction on .NET 5+ and .NET Core. [#1624](https://github.com/dotnet/SqlClient/pull/1624)
+- Parallelize SSRP requests on Linux and macOS when MultiSubNetFailover is specified. [#1578](https://github.com/dotnet/SqlClient/pull/1578)
+- Fixed connection failure by skipping Certificate Revocation List (CRL) check during authentication. [#1559](https://github.com/dotnet/SqlClient/pull/1559)
+- Fixed thread safety issue for `GetEnclaveProvider` by converting dictionary to concurrent dictionary. [#1451](https://github.com/dotnet/SqlClient/pull/1451)
+
+### Changed
+
+- Updated `AuthProviderInfo` struct to be matched the changes in native SNI for `TDS 8` server certificate validation. [#1680](https://github.com/dotnet/SqlClient/pull/1680)
+- Updated default system protocol for `TDS 8` on managed code. [#1678](https://github.com/dotnet/SqlClient/pull/1678)
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.0.0`. [#1608](https://github.com/dotnet/SqlClient/pull/1608)
+- Changed encoding UTF-7 to ASCII for SSRP Broadcast. [#1671](https://github.com/dotnet/SqlClient/pull/1671)
+- Updated `IdentityModel` dependency from 6.8.0 to 6.21.0 and `IdentityClient` from 4.32.2 to 4.45.0. [#1646](https://github.com/dotnet/SqlClient/pull/1646)
+- Updated **Azure Identity** dependency from 1.5.0 to 1.6.0. [#1611](https://github.com/dotnet/SqlClient/pull/1611)
+- Improved Regex for `SqlCommandSet`. [#1548](https://github.com/dotnet/SqlClient/pull/1548)
+- Adjust the default **ConnectRetryCount** against Azure Synapse OnDemand endpoints. [#1626](https://github.com/dotnet/SqlClient/pull/1626)
+- Updated `Azure.Identity` version to `1.5.0` and `Microsoft.Identity.Client` version to `4.30.1`. [#1462](https://github.com/dotnet/SqlClient/pull/1462)
+- Replaced `AlwaysEncryptedAttestationException` with `SqlException`. [#1515](https://github.com/dotnet/SqlClient/pull/1515)
+- Improved error message when adding wrong type to `SqlParameterCollection`. [#1547](https://github.com/dotnet/SqlClient/pull/1547)
+- Changed SQL server codenames to version names in the code. [#1439](https://github.com/dotnet/SqlClient/pull/1439)
+- Changed `Array.Copy` to `Buffer.BlockCopy` for byte arrays. [#1366](https://github.com/dotnet/SqlClient/pull/1366)
+- Various code improvements: [#1197](https://github.com/dotnet/SqlClient/pull/1197), [#1313](https://github.com/dotnet/SqlClient/pull/1313), [#1330](https://github.com/dotnet/SqlClient/pull/1330), [#1366](https://github.com/dotnet/SqlClient/pull/1366), [#1435](https://github.com/dotnet/SqlClient/pull/1435), [#1478](https://github.com/dotnet/SqlClient/pull/1478), [#1353](https://github.com/dotnet/SqlClient/pull/1353), [#1354](https://github.com/dotnet/SqlClient/pull/1354), [#1525](https://github.com/dotnet/SqlClient/pull/1525), [#1186](https://github.com/dotnet/SqlClient/pull/1186), [#1343](https://github.com/dotnet/SqlClient/pull/1343), [#1370](https://github.com/dotnet/SqlClient/pull/1370), [#1371](https://github.com/dotnet/SqlClient/pull/1371), [#1438](https://github.com/dotnet/SqlClient/pull/1438), [#1483](https://github.com/dotnet/SqlClient/pull/1483), [#1351](https://github.com/dotnet/SqlClient/pull/1351), [#1452](https://github.com/dotnet/SqlClient/pull/1452), [#1364](https://github.com/dotnet/SqlClient/pull/1364),[#1337](https://github.com/dotnet/SqlClient/pull/1337), [#1346](https://github.com/dotnet/SqlClient/pull/1346), [#1339](https://github.com/dotnet/SqlClient/pull/1339), [#1555](https://github.com/dotnet/SqlClient/pull/1555)
+
+
+### TDS 8 Enhanced Security
+
+To use TDS 8.0, specify Encrypt=Strict in the connection string. Strict mode disables TrustServerCertificate (always treated as False in Strict mode). HostNameInCertificate has been added to help some Strict mode scenarios. TDS 8 begins and continues all server communication inside a secure, encrypted TLS connection.
+
+New Encrypt values have been added to clarify connection encryption behavior. Encrypt=Mandatory is equivalent to Encrypt=True and encrypts connections during the TDS connection negotiation. Encrypt=Optional is equivalent to Encrypt=False and only encrypts the connection if the server tells the client that encryption is required during the TDS connection negotiation.
+
+HostNameInCertificate can be specified in the connection string when using aliases to connect with encryption to a server that has a server certificate with a different name or alternate subject name than the name used by the client to identify the server (DNS aliases, for example). Example usage: HostNameInCertificate=MyDnsAliasName
+
+To read more about TDS 8.0 in SQL Server, see the [SQL Server online documentation](https://docs.microsoft.com/sql/relational-databases/security/networking/tds-8-and-tls-1-3).
+
+### Server SPN
+
+When connecting in an environment that has unique domain/forest topography, the ServerSPN/Server SPN and FailoverServerSPN/Failover Server SPN connection string settings can be used to override the auto-generated server SPNs used in the library when authenticating with integrated authentication in a domain environment.
+
+### Support for Aliases
+
+Users can configure Aliases by using the SQL Server Configuration Manager. These are stored in the Windows registry and are already supported when targeting .NET Framework. This release brings support for aliases when targeting .NET or .NET Core on Windows.
+
+
+### SQL Data Source Enumerator support
+Provides a mechanism for enumerating all available instances of SQL Server within the local network.
+```cs
+using Microsoft.Data.Sql;
+
+static void Main()
+ {
+ // Retrieve the enumerator instance and then the data.
+ SqlDataSourceEnumerator instance =
+ SqlDataSourceEnumerator.Instance;
+ System.Data.DataTable table = instance.GetDataSources();
+
+ // Display the contents of the table.
+ DisplayData(table);
+
+ Console.WriteLine("Press any key to continue.");
+ Console.ReadKey();
+ }
+
+ private static void DisplayData(System.Data.DataTable table)
+ {
+ foreach (System.Data.DataRow row in table.Rows)
+ {
+ foreach (System.Data.DataColumn col in table.Columns)
+ {
+ Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
+ }
+ Console.WriteLine("============================");
+ }
+ }
+```
+
+### New Attestation protocol `None`
+A new attestation protocol called `None` is allowed in the connection string. This protocol will allow users to forgo enclave attestation for `VBS` enclaves. When this protocol is set, the enclave attestation URL property is optional.
+
+Connection string example:
+
+```cs
+//Attestation protocol NONE with no URL
+"Data Source = {server}; Initial Catalog = {db}; Column Encryption Setting = Enabled; Attestation Protocol = None;"
+
+```
+
+### Suppress insecure TLS warnings
+A security warning is output to the console if a TLS version less than 1.2 is used to negotiate encryption with the server. This warning can be suppressed on connections where `Encrypt = false` by enabling the following AppContext switch at application startup:
+```cs
+Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning
+```
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 5.0.0
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encoding.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.0
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.Loader 4.3.0
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/5.0/5.0.1.md b/release-notes/5.0/5.0.1.md
new file mode 100644
index 0000000000..39d36cc579
--- /dev/null
+++ b/release-notes/5.0/5.0.1.md
@@ -0,0 +1,81 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.0.1 released 7 October 2022
+
+This update includes the following changes over the 5.0.0 release:
+
+### Fixed
+
+- Fixed missing `HostNameInCertificate` connection string property in .NET Framework. [#1782](https://github.com/dotnet/SqlClient/pull/1782)
+- Fixed async deadlock issue when sending attention fails due to network failure. [#1783](https://github.com/dotnet/SqlClient/pull/1783)
+- Fixed **Null Reference Exception** on assigning `null` to `SqlConnectionStringBuilder.Encrypt`. [#1784](https://github.com/dotnet/SqlClient/pull/1784)
+- Fixed `ReadAsync()` behavior to register Cancellation token action before streaming results. [#1785](https://github.com/dotnet/SqlClient/pull/1785)
+- Fixed hang on infinite timeout and managed SNI. [#1798](https://github.com/dotnet/SqlClient/pull/1798)
+- Fixed Default UTF8 collation conflict. [#1799](https://github.com/dotnet/SqlClient/pull/1799)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.0.1` [#1795](https://github.com/dotnet/SqlClient/pull/1795), which includes the fix for AppDomain crash introducing in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418).
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 5.0.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encoding.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI.runtime 5.0.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.Loader 4.3.0
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/5.0/5.0.md b/release-notes/5.0/5.0.md
new file mode 100644
index 0000000000..ec3dbc7eb6
--- /dev/null
+++ b/release-notes/5.0/5.0.md
@@ -0,0 +1,16 @@
+# Microsoft.Data.SqlClient 5.0 Releases
+
+The following Microsoft.Data.SqlClient 5.0 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/10/07 | 5.0.1 | [release notes](5.0.1.md) |
+| 2022/08/05 | 5.0.0 | [release notes](5.0.0.md) |
+
+The following Microsoft.Data.SqlClient 5.0 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/06/16 | 5.0.0-preview3.22168.1 | [release notes](5.0.0-preview3.md) |
+| 2022/04/06 | 5.0.0-preview2.22096.2 | [release notes](5.0.0-preview2.md) |
+| 2022/03/09 | 5.0.0-preview1.22069.1 | [release notes](5.0.0-preview1.md) |
diff --git a/release-notes/5.0/README.md b/release-notes/5.0/README.md
new file mode 100644
index 0000000000..ec3dbc7eb6
--- /dev/null
+++ b/release-notes/5.0/README.md
@@ -0,0 +1,16 @@
+# Microsoft.Data.SqlClient 5.0 Releases
+
+The following Microsoft.Data.SqlClient 5.0 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/10/07 | 5.0.1 | [release notes](5.0.1.md) |
+| 2022/08/05 | 5.0.0 | [release notes](5.0.0.md) |
+
+The following Microsoft.Data.SqlClient 5.0 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/06/16 | 5.0.0-preview3.22168.1 | [release notes](5.0.0-preview3.md) |
+| 2022/04/06 | 5.0.0-preview2.22096.2 | [release notes](5.0.0-preview2.md) |
+| 2022/03/09 | 5.0.0-preview1.22069.1 | [release notes](5.0.0-preview1.md) |
diff --git a/release-notes/5.1/5.1.0-preview1.md b/release-notes/5.1/5.1.0-preview1.md
new file mode 100644
index 0000000000..222f10f7d5
--- /dev/null
+++ b/release-notes/5.1/5.1.0-preview1.md
@@ -0,0 +1,89 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.1.0-preview1.22279.3 released 19 October 2022
+
+This update brings the below changes over the previous release:
+
+### Fixed
+
+- Fixed `ReadAsync()` behavior to register Cancellation token action before streaming results. [#1781](https://github.com/dotnet/SqlClient/pull/1781)
+- Fixed `NullReferenceException` when assigning `null` to `SqlConnectionStringBuilder.Encrypt`. [#1778](https://github.com/dotnet/SqlClient/pull/1778)
+- Fixed missing `HostNameInCertificate` property in .NET Framework Reference Project. [#1776](https://github.com/dotnet/SqlClient/pull/1776)
+- Fixed async deadlock issue when sending attention fails due to network failure. [#1766](https://github.com/dotnet/SqlClient/pull/1766)
+- Fixed failed connection requests in ConnectionPool in case of PoolBlock. [#1768](https://github.com/dotnet/SqlClient/pull/1768)
+- Fixed hang on infinite timeout and managed SNI. [#1742](https://github.com/dotnet/SqlClient/pull/1742)
+- Fixed Default UTF8 collation conflict. [#1739](https://github.com/dotnet/SqlClient/pull/1739)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.1.0-preview1.22278.1`. [#1787](https://github.com/dotnet/SqlClient/pull/1787) which includes TLS 1.3 Support and fix for AppDomain crash in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418)
+- Changed the `SqlConnectionEncryptOption` string parser to public. [#1771](https://github.com/dotnet/SqlClient/pull/1771)
+- Converted `ExecuteNonQueryAsync` to use async context object. [#1692](https://github.com/dotnet/SqlClient/pull/1692)
+- Code health improvements [#1604](https://github.com/dotnet/SqlClient/pull/1604) [#1598](https://github.com/dotnet/SqlClient/pull/1598) [#1595](https://github.com/dotnet/SqlClient/pull/1595) [#1443](https://github.com/dotnet/SqlClient/pull/1443)
+
+### Known issues
+
+- When using `Encrypt=Strict` with TLS v1.3, the TLS handshake occurs twice on initial connection on .NET Framework due to a timeout during the TLS handshake and a retry helper re-establishes the connection; however, on .NET Core, it will throw a `System.ComponentModel.Win32Exception (258): The wait operation timed out.` and is being investigated. If you're using Microsoft.Data.SqlClient with .NET Core on Windows 11, you will need to enable the managed SNI on Windows context switch using following statement `AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);` to use TLS v1.3 or disabling TLS 1.3 from the registry by assigning `0` to the following `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client\Enabled` registry key and it'll use TLS v1.2 for the connection. This will be fixed in a future release.
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows x86, Windows x64)
+- .NET Core 3.1+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 5.1.0.preview1.22278.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encoding.Web 4.7.2
+
+#### .NET Core
+
+- Microsoft.Data.SqlClient.SNI 5.1.0.preview1.22278.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.Diagnostics.DiagnosticSource 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI 5.1.0.preview1.22278.1
+- Azure.Identity 1.6.0
+- Microsoft.Identity.Client 4.45.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.21.0
+- Microsoft.IdentityModel.JsonWebTokens 6.21.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 5.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 5.0.0
+- System.Text.Encoding.CodePages 5.0.0
+- System.Text.Encodings.Web 4.7.2
+- System.Runtime.Loader 4.3.0
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/5.1/5.1.0-preview2.md b/release-notes/5.1/5.1.0-preview2.md
new file mode 100644
index 0000000000..93b58078a0
--- /dev/null
+++ b/release-notes/5.1/5.1.0-preview2.md
@@ -0,0 +1,98 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.1.0-preview2.22314.2 released 10 November 2022
+
+This update brings the below changes over the previous release:
+
+### Breaking changes over preview release v5.1.0-preview1
+
+- Add support for .NET 6.0 and Dropped support for .NET Core 3.1. [#1704](https://github.com/dotnet/SqlClient/pull/1704) [#1823](https://github.com/dotnet/SqlClient/pull/1823)
+
+### Added
+
+- Added support for `DateOnly` and `TimeOnly` for `SqlParameter` value and `GetFieldValue`. [#1813](https://github.com/dotnet/SqlClient/pull/1813)
+- Added support for TLS 1.3 for .NET Core and SNI Native. [#1821](https://github.com/dotnet/SqlClient/pull/1821)
+- Added `ServerCertificate` support for `Encrypt=Mandatory` or `Encrypt=Strict`. [#1822](https://github.com/dotnet/SqlClient/pull/1822) [Read more](#server-certificate-support)
+- Added Windows ARM64 support when targeting .NET Framework. [#1828](https://github.com/dotnet/SqlClient/pull/1828)
+
+### Fixed
+
+- Fixed memory leak regression from [#1781](https://github.com/dotnet/SqlClient/pull/1781) using a `DisposableTemporaryOnStack` struct. [#1818](https://github.com/dotnet/SqlClient/pull/1818)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.1.0-preview2.22311.2`. [#1831](https://github.com/dotnet/SqlClient/pull/1831) which includes the fix for the TLS 1.3 timeout and double handshake issue, removal of ARM32 binaries, and support for the `ServerCertificate` option. [#1822](https://github.com/dotnet/SqlClient/issues/1822) [Read more](#server-certificate-support)
+- Reverted "Excluding unsupported TLS protocols" for issue [#1151](https://github.com/dotnet/SqlClient/issues/1151) (i.e. removed `Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS`) by adding support for TLS 1.3. [#1824](https://github.com/dotnet/SqlClient/issues/1824)
+- Code health improvements [#1812](https://github.com/dotnet/SqlClient/pull/1812) [#1520](https://github.com/dotnet/SqlClient/pull/1520)
+
+## New features
+
+### Server Certificate Support
+The default value of the `ServerCertificate` connection setting is an empty string. When `Encrypt` is set to `Mandatory` or `Strict`, `ServerCertificate` can be used to specify a path on the file system to a certificate file to match against the SQL Server's TLS/SSL certificate. For this to be valid, the certificate specified must be an exact match. The accepted certificate formats are `PEM`, `DER`, and `CER`. Here is an usage example:
+
+ ```cs
+ "Data Source=...;Encrypt=Strict;ServerCertificate=C:\\certificates\\server.cer"
+ ```
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows x86, Windows x64)
+- .NET 6.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 5.1.0.preview2.22311.2
+- Azure.Identity 1.7.0
+- Microsoft.Identity.Client 4.47.2
+- Microsoft.IdentityModel.JsonWebTokens 6.24.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 6.0.1
+- System.IO 4.3.0
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Security.Cryptography.Algorithms 4.3.1
+- System.Security.Cryptography.Primitives 4.3.0
+- System.Text.Encoding.Web 6.0.0
+
+#### .NET
+
+- Microsoft.Data.SqlClient.SNI 5.1.0.preview2.22311.2
+- Azure.Identity 1.7.0
+- Microsoft.Identity.Client 4.47.2
+- Microsoft.IdentityModel.JsonWebTokens 6.24.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 6.0.1
+- System.Diagnostics.DiagnosticSource 6.0.0
+- System.IO 4.3.0
+- System.Runtime.Caching 6.0.0
+- System.Text.Encoding.CodePages 6.0.0
+- System.Text.Encodings.Web 6.0.0
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI 5.1.0.preview2.22311.2
+- Azure.Identity 1.7.0
+- Microsoft.Identity.Client 4.47.2
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0
+- Microsoft.IdentityModel.JsonWebTokens 6.24.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 6.0.1
+- System.IO 4.3.0
+- System.Runtime.Caching 6.0.0
+- System.Text.Encoding.CodePages 6.0.0
+- System.Text.Encodings.Web 6.0.0
+- System.Runtime.Loader 4.3.0
+- System.Resources.ResourceManager 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/5.1/5.1.0.md b/release-notes/5.1/5.1.0.md
new file mode 100644
index 0000000000..015b8966b9
--- /dev/null
+++ b/release-notes/5.1/5.1.0.md
@@ -0,0 +1,103 @@
+# Release Notes
+
+## Microsoft.Data.SqlClient 5.1.0 released 19 January 2023
+
+This update includes the following changes over the 5.0 release:
+
+### Breaking changes
+
+- Dropped support for .NET Core 3.1. [#1704](https://github.com/dotnet/SqlClient/pull/1704) [#1823](https://github.com/dotnet/SqlClient/pull/1823)
+
+### Added
+
+- Added support for .NET 6.0. [#1704](https://github.com/dotnet/SqlClient/pull/1704)
+- Added support for `DateOnly` and `TimeOnly` for `SqlParameter` value and `GetFieldValue`. [#1813](https://github.com/dotnet/SqlClient/pull/1813)
+- Added support for TLS 1.3 on .NET Core and native SNI. [#1821](https://github.com/dotnet/SqlClient/pull/1821)
+- Added `ServerCertificate` setting for `Encrypt=Mandatory` or `Encrypt=Strict`. [#1822](https://github.com/dotnet/SqlClient/pull/1822) [Read more](#server-certificate)
+- Added Windows ARM64 support when targeting .NET Framework. [#1828](https://github.com/dotnet/SqlClient/pull/1828)
+
+### Fixed
+
+- Fixed thread safety of transient error list in configurable retry logic. [#1882](https://github.com/dotnet/SqlClient/pull/1882)
+- Fixed deadlock when using SinglePhaseCommit with distributed transactions. [#1801](https://github.com/dotnet/SqlClient/pull/1801)
+- Fixed Dedicated Admin Connections (DAC) to localhost in managed SNI [#1865](https://github.com/dotnet/SqlClient/pull/1865)
+- Fixed memory leak regression from [#1781](https://github.com/dotnet/SqlClient/pull/1781) using a `DisposableTemporaryOnStack` struct. [#1818](https://github.com/dotnet/SqlClient/pull/1818)
+- Fixed `ReadAsync()` behavior to register Cancellation token action before streaming results. [#1781](https://github.com/dotnet/SqlClient/pull/1781)
+- Fixed `NullReferenceException` when assigning `null` to `SqlConnectionStringBuilder.Encrypt`. [#1778](https://github.com/dotnet/SqlClient/pull/1778)
+- Fixed missing `HostNameInCertificate` property in .NET Framework Reference Project. [#1776](https://github.com/dotnet/SqlClient/pull/1776)
+- Fixed async deadlock issue when sending attention fails due to network failure. [#1766](https://github.com/dotnet/SqlClient/pull/1766)
+- Fixed failed connection requests in ConnectionPool in case of PoolBlock. [#1768](https://github.com/dotnet/SqlClient/pull/1768)
+- Fixed hang on infinite timeout and managed SNI. [#1742](https://github.com/dotnet/SqlClient/pull/1742)
+- Fixed Default UTF8 collation conflict. [#1739](https://github.com/dotnet/SqlClient/pull/1739)
+
+### Changed
+
+- Updated `Microsoft.Data.SqlClient.SNI` (.NET Framework dependency) and `Microsoft.Data.SqlClient.SNI.runtime` (.NET Core/Standard dependency) version to `5.1.0`. [#1889](https://github.com/dotnet/SqlClient/pull/1889) which includes fix for AppDomain crash in issue [#1418](https://github.com/dotnet/SqlClient/issues/1418), TLS 1.3 Support, removal of ARM32 binaries, and support for the `ServerCertificate` option. [#1822](https://github.com/dotnet/SqlClient/issues/1822) [Read more](#server-certificate)
+- Reverted "Excluding unsupported TLS protocols" for issue [#1151](https://github.com/dotnet/SqlClient/issues/1151) (i.e. removed `Switch.Microsoft.Data.SqlClient.EnableSecureProtocolsByOS`) by adding support for TLS 1.3. [#1824](https://github.com/dotnet/SqlClient/issues/1824)
+- Changed the `SqlConnectionEncryptOption` string parser to public. [#1771](https://github.com/dotnet/SqlClient/pull/1771)
+- Converted `ExecuteNonQueryAsync` to use async context object. [#1692](https://github.com/dotnet/SqlClient/pull/1692)
+- Code health improvements [#1867](https://github.com/dotnet/SqlClient/pull/1867) [#1849](https://github.com/dotnet/SqlClient/pull/1849) [#1812](https://github.com/dotnet/SqlClient/pull/1812) [#1520](https://github.com/dotnet/SqlClient/pull/1520) [#1604](https://github.com/dotnet/SqlClient/pull/1604) [#1598](https://github.com/dotnet/SqlClient/pull/1598) [#1595](https://github.com/dotnet/SqlClient/pull/1595) [#1443](https://github.com/dotnet/SqlClient/pull/1443)
+
+## New features
+
+### Server Certificate
+
+The default value of the `ServerCertificate` connection setting is an empty string. When `Encrypt` is set to `Mandatory` or `Strict`, `ServerCertificate` can be used to specify a path on the file system to a certificate file to match against the SQL Server's TLS/SSL certificate. For this to be valid, the certificate specified must be an exact match. The accepted certificate formats are `PEM`, `DER`, and `CER`. Here is an example:
+
+ ```cs
+ "Data Source=...;Encrypt=Strict;ServerCertificate=C:\\certificates\\server.cer"
+ ```
+
+## Target Platform Support
+
+- .NET Framework 4.6.2+ (Windows x86, Windows x64)
+- .NET 6.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+- .NET Standard 2.0+ (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Data.SqlClient.SNI 5.1.0
+- Azure.Identity 1.7.0
+- Microsoft.Identity.Client 4.47.2
+- Microsoft.IdentityModel.JsonWebTokens 6.24.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 6.0.1
+- System.Runtime.InteropServices.RuntimeInformation 4.3.0
+- System.Text.Encoding.Web 6.0.0
+
+#### .NET
+
+- Microsoft.Data.SqlClient.SNI 5.1.0
+- Azure.Identity 1.7.0
+- Microsoft.Identity.Client 4.47.2
+- Microsoft.IdentityModel.JsonWebTokens 6.24.0
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0
+- Microsoft.SqlServer.Server 1.0.0
+- System.Configuration.ConfigurationManager 6.0.1
+- System.Diagnostics.DiagnosticSource 6.0.0
+- System.Runtime.Caching 6.0.0
+- System.Text.Encoding.CodePages 6.0.0
+- System.Text.Encodings.Web 6.0.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
+
+#### .NET Standard
+
+- Microsoft.Data.SqlClient.SNI 5.1.0
+- Azure.Identity 1.7.0
+- Microsoft.Identity.Client 4.47.2
+- Microsoft.IdentityModel.Protocols.OpenIdConnect 6.24.0
+- Microsoft.IdentityModel.JsonWebTokens 6.24.0
+- Microsoft.SqlServer.Server 1.0.0
+- Microsoft.Win32.Registry 5.0.0
+- System.Buffers 4.5.1
+- System.Configuration.ConfigurationManager 6.0.1
+- System.Runtime.Caching 6.0.0
+- System.Text.Encoding.CodePages 6.0.0
+- System.Text.Encodings.Web 6.0.0
+- System.Runtime.Loader 4.3.0
+- System.Security.Cryptography.Cng 5.0.0
+- System.Security.Principal.Windows 5.0.0
diff --git a/release-notes/5.1/5.1.md b/release-notes/5.1/5.1.md
new file mode 100644
index 0000000000..6f6687b5d5
--- /dev/null
+++ b/release-notes/5.1/5.1.md
@@ -0,0 +1,14 @@
+# Microsoft.Data.SqlClient 5.1 Releases
+
+The following Microsoft.Data.SqlClient 5.1 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2023/01/19 | 5.1.0 | [release notes](5.1.0.md) |
+
+The following Microsoft.Data.SqlClient 5.1 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/11/10 | 5.1.0-preview2.22314.2 | [release notes](5.1.0-preview2.md) |
+| 2022/10/19 | 5.1.0-preview1.22279.3 | [release notes](5.1.0-preview1.md) |
diff --git a/release-notes/5.1/README.md b/release-notes/5.1/README.md
new file mode 100644
index 0000000000..6f6687b5d5
--- /dev/null
+++ b/release-notes/5.1/README.md
@@ -0,0 +1,14 @@
+# Microsoft.Data.SqlClient 5.1 Releases
+
+The following Microsoft.Data.SqlClient 5.1 stable releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2023/01/19 | 5.1.0 | [release notes](5.1.0.md) |
+
+The following Microsoft.Data.SqlClient 5.1 preview releases have been shipped:
+
+| Release Date | Version | Notes |
+| :-- | :-- | :--: |
+| 2022/11/10 | 5.1.0-preview2.22314.2 | [release notes](5.1.0-preview2.md) |
+| 2022/10/19 | 5.1.0-preview1.22279.3 | [release notes](5.1.0-preview1.md) |
diff --git a/release-notes/MSqlServerServer/1.0/1.0.0.md b/release-notes/MSqlServerServer/1.0/1.0.0.md
new file mode 100644
index 0000000000..72072f174a
--- /dev/null
+++ b/release-notes/MSqlServerServer/1.0/1.0.0.md
@@ -0,0 +1,42 @@
+# Release Notes
+
+## General Availability of Microsoft.SqlServer.Server
+
+_**1.0.0 released 28 January 2022**_
+
+This is the initial public stable release of the **Microsoft.SqlServer.Server** namespace in a separate assembly. This library is a dependency for **Microsoft.Data.SqlClient** enabling cross framework support of UDT types.
+
+### Supported types
+
+#### Targeting .NET Standard 2.0
+
+- Microsoft.SqlServer.Server.DataAccessKind
+- Microsoft.SqlServer.Server.Format
+- Microsoft.SqlServer.Server.IBinarySerialize
+- Microsoft.SqlServer.Server.InvalidUdtException
+- Microsoft.SqlServer.Server.SqlFacetAttribute
+- Microsoft.SqlServer.Server.SqlFunctionAttribute
+- Microsoft.SqlServer.Server.SqlMethodAttribute
+- Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
+- Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
+- Microsoft.SqlServer.Server.SystemDataAccessKind
+
+#### Targeting .NET Framework 4.6+
+
+Following types forwarded to `System.Data`:
+
+- Microsoft.SqlServer.Server.DataAccessKind
+- Microsoft.SqlServer.Server.Format
+- Microsoft.SqlServer.Server.IBinarySerialize
+- Microsoft.SqlServer.Server.InvalidUdtException
+- Microsoft.SqlServer.Server.SqlFacetAttribute
+- Microsoft.SqlServer.Server.SqlFunctionAttribute
+- Microsoft.SqlServer.Server.SqlMethodAttribute
+- Microsoft.SqlServer.Server.SqlUserDefinedAggregateAttribute
+- Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute
+- Microsoft.SqlServer.Server.SystemDataAccessKind
+
+## Target Platform Support
+
+- .NET Framework 4.6+ (Windows x86, Windows x64)
+- .NET Standard 2.0 (Windows x86, Windows x64, Windows ARM64, Windows ARM, Linux, macOS)
diff --git a/release-notes/MSqlServerServer/1.0/README.md b/release-notes/MSqlServerServer/1.0/README.md
new file mode 100644
index 0000000000..ffe4befce8
--- /dev/null
+++ b/release-notes/MSqlServerServer/1.0/README.md
@@ -0,0 +1,7 @@
+# Microsoft.SqlServer.Server 1.0 Releases
+
+The following Microsoft.SqlServer.Server 1.0 stable release has been shipped:
+
+| Release Date | Description | Notes |
+| :-- | :-- | :--: |
+| 2022/01/28 | 1.0.0 | [release notes](1.0.0.md) |
diff --git a/release-notes/README.md b/release-notes/README.md
index fc3dcf3315..ba76fe8433 100644
--- a/release-notes/README.md
+++ b/release-notes/README.md
@@ -1,9 +1,15 @@
# Microsoft.Data.SqlClient Release Notes
-The latest stable release is [Microsoft.Data.SqlClient 2.1](2.1).
+The latest stable release is [Microsoft.Data.SqlClient 5.0](5.0).
## Release Information
+- [Microsoft.Data.SqlClient 5.1](5.1)
+- [Microsoft.Data.SqlClient 5.0](5.0)
+- [Microsoft.Data.SqlClient 4.1](4.1)
+- [Microsoft.Data.SqlClient 4.0](4.0)
+- [Microsoft.Data.SqlClient 3.0](3.0)
+- [Microsoft.Data.SqlClient 3.1](3.1)
- [Microsoft.Data.SqlClient 2.1](2.1)
- [Microsoft.Data.SqlClient 2.0](2.0)
- [Microsoft.Data.SqlClient 1.1](1.1)
@@ -11,8 +17,20 @@ The latest stable release is [Microsoft.Data.SqlClient 2.1](2.1).
# Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider Release Notes
-The latest stable release is [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.0](add-ons/AzureKeyVaultProvider/1.0).
+The latest stable release is [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 3.0](add-ons/AzureKeyVaultProvider/3.0).
## Release Information
+- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 3.0](add-ons/AzureKeyVaultProvider/3.0)
+- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 2.0](add-ons/AzureKeyVaultProvider/2.0)
+- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.2](add-ons/AzureKeyVaultProvider/1.2)
+- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.1](add-ons/AzureKeyVaultProvider/1.1)
- [Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.0](add-ons/AzureKeyVaultProvider/1.0)
+
+# Microsoft.SqlServer.Server Release Notes
+
+The latest stable release is [Microsoft.SqlServer.Server 1.0](MSqlServerServer/1.0).
+
+## Release Information
+
+- [Microsoft.SqlServer.Server 1.0](MSqlServerServer/1.0)
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/1.1/1.1.1.md b/release-notes/add-ons/AzureKeyVaultProvider/1.1/1.1.1.md
new file mode 100644
index 0000000000..6fd241bbbf
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/1.1/1.1.1.md
@@ -0,0 +1,36 @@
+# Release Notes
+
+## General Availability of Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+_**1.1.1 released 02 March 2020**_
+
+This library contains the implementation of `Microsoft.Data.SqlClient.SqlColumnEncryptionKeyStoreProvider` for accessing Azure Key Vault, and the provider class is named `SqlColumnEncryptionAzureKeyVaultProvider`.
+
+### Working with SQLColumnEncryptionAzureKeyVaultProvider
+`SqlColumnEncryptionAzureKeyVaultProvider` is implemented against `Microsoft.Data.SqlClient` and supports .NET Framework 4.6+ and .NET Core 2.1+. The provider name identifier for this library is "**AZURE_KEY_VAULT**" and it is not registered in the driver by default. Client applications may call the `SqlConnection.RegisterColumnEncryptionKeyStoreProviders()` API once in the lifetime of the driver to register this custom provider by implementing a custom Authentication Callback mechanism.
+
+Once the provider is registered, it can used to perform Always Encrypted operations by creating a Column Master Key using the Azure Key Vault Key Identifier URL.
+
+A sample C# application to demonstrate Always Encrypted with Azure Key Vault can be download from the samples directory: [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/master/doc/samples/AzureKeyVaultProviderExample.cs)
+
+## Target Platform Support
+
+- .NET Framework 4.6+
+- .NET Core 2.1+ (Windows x86, Windows x64, Linux, macOS)
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Azure.KeyVault 3.0.4
+- Microsoft.Azure.KeyVault.WebKey 3.0.4
+- Microsoft.Data.SqlClient 1.0.19269.1
+- Microsoft.Rest.ClientRuntime 2.3.20
+- Microsoft.Rest.ClientRuntime.Azure 3.3.19
+
+#### .NET Core
+
+- Microsoft.Azure.KeyVault 3.0.4
+- Microsoft.Azure.KeyVault.WebKey 3.0.4
+- Microsoft.Data.SqlClient 1.0.19269.1
+- Microsoft.Rest.ClientRuntime 2.3.20
+- Microsoft.Rest.ClientRuntime.Azure 3.3.19
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/1.1/README.md b/release-notes/add-ons/AzureKeyVaultProvider/1.1/README.md
new file mode 100644
index 0000000000..eed9f0741b
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/1.1/README.md
@@ -0,0 +1,7 @@
+# Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.1 Releases
+
+The following Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.1 stable releases have been shipped:
+
+| Release Date | Description | Notes |
+| :-- | :-- | :--: |
+| 2020/03/02 | 1.1.1 | [release notes](1.1.1.md) |
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/1.2/1.2.0.md b/release-notes/add-ons/AzureKeyVaultProvider/1.2/1.2.0.md
new file mode 100644
index 0000000000..a4ed97335c
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/1.2/1.2.0.md
@@ -0,0 +1,51 @@
+# Release Notes
+
+## General Availability of Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+_**1.2.0 released 01 December 2020**_
+
+This library contains the implementation of `Microsoft.Data.SqlClient.SqlColumnEncryptionKeyStoreProvider` for accessing Azure Key Vault, and the provider class is named `SqlColumnEncryptionAzureKeyVaultProvider`.
+
+### Added
+
+- Added support for .NET Standard 2.0. This requires Microsoft.Data.SqlClient v2.1.0 and above. [#823](https://github.com/dotnet/SqlClient/pull/823)
+- Added new HSM endpoints. [#750](https://github.com/dotnet/SqlClient/pull/750)
+- Added source linked PDBs for easier debugging of the package. [#789](https://github.com/dotnet/SqlClient/pull/789)
+
+### Working with SQLColumnEncryptionAzureKeyVaultProvider
+`SqlColumnEncryptionAzureKeyVaultProvider` is implemented against `Microsoft.Data.SqlClient` and supports .NET Framework 4.6+, .NET Core 2.1+, and .NET Standard 2.0+. The provider name identifier for this library is "**AZURE_KEY_VAULT**" and it is not registered in the driver by default. Client applications may call the `SqlConnection.RegisterColumnEncryptionKeyStoreProviders()` API once in the lifetime of the driver to register this custom provider by implementing a custom Authentication Callback mechanism.
+
+Once the provider is registered, it can be used to perform Always Encrypted operations by creating a Column Master Key using the Azure Key Vault Key Identifier URL.
+
+A sample C# application to demonstrate Always Encrypted with Azure Key Vault can be download from the samples directory: [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/master/doc/samples/AzureKeyVaultProviderExample.cs)
+
+## Target Platform Support
+
+- .NET Framework 4.6+
+- .NET Core 2.1+ (Windows x86, Windows x64, Linux, macOS)
+- .NET Standard 2.0+
+
+### Dependencies
+
+#### .NET Framework
+
+- Microsoft.Azure.KeyVault 3.0.4
+- Microsoft.Azure.KeyVault.WebKey 3.0.4
+- Microsoft.Data.SqlClient 1.0.19269.1
+- Microsoft.Rest.ClientRuntime 2.3.20
+- Microsoft.Rest.ClientRuntime.Azure 3.3.19
+
+#### .NET Core
+
+- Microsoft.Azure.KeyVault 3.0.4
+- Microsoft.Azure.KeyVault.WebKey 3.0.4
+- Microsoft.Data.SqlClient 1.0.19269.1
+- Microsoft.Rest.ClientRuntime 2.3.20
+- Microsoft.Rest.ClientRuntime.Azure 3.3.19
+
+#### .NET Standard
+
+- Microsoft.Azure.KeyVault 3.0.4
+- Microsoft.Azure.KeyVault.WebKey 3.0.4
+- Microsoft.Data.SqlClient 2.1.0
+- Microsoft.Rest.ClientRuntime 2.3.20
+- Microsoft.Rest.ClientRuntime.Azure 3.3.19
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/1.2/README.md b/release-notes/add-ons/AzureKeyVaultProvider/1.2/README.md
new file mode 100644
index 0000000000..43cd6f62f3
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/1.2/README.md
@@ -0,0 +1,7 @@
+# Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.2 Releases
+
+The following Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 1.2 stable releases have been shipped:
+
+| Release Date | Description | Notes |
+| :-- | :-- | :--: |
+| 2020/12/01 | 1.2.0 | [release notes](1.2.0.md) |
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/2.0/2.0.0.md b/release-notes/add-ons/AzureKeyVaultProvider/2.0/2.0.0.md
new file mode 100644
index 0000000000..b798c2e581
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/2.0/2.0.0.md
@@ -0,0 +1,52 @@
+# Release Notes
+
+## General Availability of Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+_**2.0.0 released 03 March 2021**_
+
+This library contains the implementation of `Microsoft.Data.SqlClient.SqlColumnEncryptionKeyStoreProvider` for accessing Azure Key Vault, and the provider class is named `SqlColumnEncryptionAzureKeyVaultProvider`.
+
+### Added
+- Upgraded Azure Key Vault Provider to use new Azure Key Vault libraries [#630](https://github.com/dotnet/SqlClient/pull/630)
+
+### Breaking Changes
+- Drops support for .NET Framework 4.6. The new minimum supported .NET Framework version is v4.6.1 [#630](https://github.com/dotnet/SqlClient/pull/630)
+- Updated dependency of Microsoft.Data.SqlClient on .NET Framework and .NET Core to LTS stable version v1.1.3+ [#946](https://github.com/dotnet/SqlClient/pull/946)
+
+
+### Working with SQLColumnEncryptionAzureKeyVaultProvider
+`SqlColumnEncryptionAzureKeyVaultProvider` is implemented against `Microsoft.Data.SqlClient` and supports .NET Framework 4.6.1+, .NET Core 2.1+, and .NET Standard 2.0+. The provider name identifier for this library is "**AZURE_KEY_VAULT**" and it is not registered in the driver by default. Client applications may now initialize this provider by providing an instance of `Azure.Core.TokenCredential` implementation and register it with the driver.
+
+Once the provider is registered, it can be used to perform Always Encrypted operations by creating a Column Master Key using the Azure Key Vault Key Identifier URL.
+
+The linked C# samples below demonstrate using Always Encrypted with secure enclaves with Azure Key Vault:
+- Legacy API support (Always Encrypted): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs)
+- New API support (Always Encrypted): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/AzureKeyVaultProviderExample_2_0.cs)
+- Legacy API support (Always Encrypted with secure enclaves): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/doc\samples\AzureKeyVaultProviderWithEnclaveProviderExample.cs)
+- New API support (Always Encrypted with secure enclaves): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/doc\samples\AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs)
+
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+
+- .NET Core 2.1+ (Windows x86, Windows x64, Linux, macOS)
+- .NET Standard 2.0+
+
+### Dependencies
+
+#### .NET Framework
+
+- Azure.Core 1.2.2
+- Azure.Security.KeyVault.Keys 4.0.3
+- Microsoft.Data.SqlClient 1.1.3
+
+#### .NET Core
+
+- Azure.Core 1.2.2
+- Azure.Security.KeyVault.Keys 4.0.3
+- Microsoft.Data.SqlClient 1.1.3
+
+#### .NET Standard
+
+- Azure.Core 1.2.2
+- Azure.Security.KeyVault.Keys 4.0.3
+- Microsoft.Data.SqlClient 2.1.0
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/2.0/README.md b/release-notes/add-ons/AzureKeyVaultProvider/2.0/README.md
new file mode 100644
index 0000000000..82bde5d29b
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/2.0/README.md
@@ -0,0 +1,7 @@
+# Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 2.0 Releases
+
+The following Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 2.0 stable releases have been shipped:
+
+| Release Date | Description | Notes |
+| :-- | :-- | :--: |
+| 2021/03/03 | 2.0.0 | [release notes](2.0.0.md) |
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/3.0/3.0.0.md b/release-notes/add-ons/AzureKeyVaultProvider/3.0/3.0.0.md
new file mode 100644
index 0000000000..cc1f90eac2
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/3.0/3.0.0.md
@@ -0,0 +1,69 @@
+# Release Notes
+
+## General Availability of Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+
+_**3.0.0 released 14 June 2021**_
+
+This library contains the implementation of `Microsoft.Data.SqlClient.SqlColumnEncryptionKeyStoreProvider` for accessing Azure Key Vault, and the provider class is named `SqlColumnEncryptionAzureKeyVaultProvider`.
+
+### Added
+
+- Introduces column encryption key caching support [#1056](https://github.com/dotnet/SqlClient/pull/1056)
+
+### Breaking Changes
+
+- Microsoft.Data.SqlClient dependency version upgraded to **v3.0.0+** [#1111](https://github.com/dotnet/SqlClient/pull/1111)
+
+### Working with SQLColumnEncryptionAzureKeyVaultProvider
+
+`SqlColumnEncryptionAzureKeyVaultProvider` **v3.0** is implemented against `Microsoft.Data.SqlClient` **v3.0** and supports .NET Framework 4.6.1+, .NET Core 2.1+, and .NET Standard 2.0+. The provider name identifier for this library is "**AZURE_KEY_VAULT**" and it is not registered in the driver by default. Client applications may initialize this provider by providing an `Azure.Core.TokenCredential` and registering it with the driver using any of the below APIs:
+
+- [SqlConnection.RegisterColumnEncryptionKeyStoreProviders](https://docs.microsoft.com/dotnet/api/microsoft.data.sqlclient.sqlconnection.registercolumnencryptionkeystoreproviders?view=sqlclient-dotnet-3.0)
+- [SqlConnection.RegisterColumnEncryptionKeyStoreProvidersOnConnection](https://docs.microsoft.com/dotnet/api/microsoft.data.sqlclient.sqlconnection.registercolumnencryptionkeystoreprovidersonconnection?view=sqlclient-dotnet-3.0) (Added in version 3.0.0)
+- [SqlCommand.RegisterColumnEncryptionKeyStoreProvidersOnCommand](https://docs.microsoft.com/dotnet/api/microsoft.data.sqlclient.sqlcommand.registercolumnencryptionkeystoreprovidersoncommand?view=sqlclient-dotnet-3.0) (Added in version 3.0.0)
+
+Once the provider is registered, it can be used to perform Always Encrypted operations by creating a Column Master Key using the Azure Key Vault Key Identifier URL.
+
+The linked C# samples below demonstrate using Always Encrypted with secure enclaves with Azure Key Vault:
+
+- Legacy API support (Always Encrypted): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/AzureKeyVaultProviderLegacyExample_2_0.cs)
+- New API support (Always Encrypted): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/AzureKeyVaultProviderExample_2_0.cs)
+- Legacy API support (Always Encrypted with secure enclaves): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/doc\samples\AzureKeyVaultProviderWithEnclaveProviderExample.cs)
+- New API support (Always Encrypted with secure enclaves): [AzureKeyVaultProviderExample.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/doc\samples\AzureKeyVaultProviderWithEnclaveProviderExample_2_0.cs)
+- Column Encryption Key cache scope example: [AzureKeyVaultProvider_ColumnEncryptionKeyCacheScope.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/AzureKeyVaultProvider_ColumnEncryptionKeyCacheScope.cs)
+- Registering custom key store provider - Connection Precedence: [RegisterCustomKeyStoreProvider_ConnectionPrecedence.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/RegisterCustomKeyStoreProvider_ConnectionPrecedence.cs)
+- Registering custom key store provider - Command Precedence: [RegisterCustomKeyStoreProvider_CommandPrecedence.cs](https://github.com/dotnet/SqlClient/blob/main/doc/samples/RegisterCustomKeyStoreProvider_CommandPrecedence.cs)
+
+For further details, refer to [Using the Azure Key Vault provider](https://docs.microsoft.com/sql/connect/ado-net/sql/sqlclient-support-always-encrypted#using-the-azure-key-vault-provider)
+
+## Target Platform Support
+
+- .NET Framework 4.6.1+
+- .NET Core 2.1+ (Windows x86, Windows x64, Linux, macOS)
+- .NET Standard 2.0+
+
+### Dependencies
+
+#### .NET Framework
+
+- Azure.Core 1.6.0
+- Azure.Security.KeyVault.Keys 4.0.3
+- Microsoft.Data.SqlClient 3.0.0
+- System.Text.Encodings.Web 4.7.2
+- Microsoft.Extensions.Caching.Memory 5.0.0
+
+#### .NET Core
+
+- Azure.Core 1.6.0
+- Azure.Security.KeyVault.Keys 4.0.3
+- Microsoft.Data.SqlClient 3.0.0
+- System.Text.Encodings.Web 4.7.2
+- Microsoft.Extensions.Caching.Memory 5.0.0
+
+#### .NET Standard
+
+- Azure.Core 1.6.0
+- Azure.Security.KeyVault.Keys 4.0.3
+- Microsoft.Data.SqlClient 3.0.0
+- System.Text.Encodings.Web 4.7.2
+- Microsoft.Extensions.Caching.Memory 5.0.0
diff --git a/release-notes/add-ons/AzureKeyVaultProvider/3.0/README.md b/release-notes/add-ons/AzureKeyVaultProvider/3.0/README.md
new file mode 100644
index 0000000000..d7deee4b63
--- /dev/null
+++ b/release-notes/add-ons/AzureKeyVaultProvider/3.0/README.md
@@ -0,0 +1,7 @@
+# Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 3.0 Releases
+
+The following Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider 3.0 stable releases have been shipped:
+
+| Release Date | Description | Notes |
+| :-- | :-- | :--: |
+| 2021/06/14 | 3.0.0 | [release notes](3.0.0.md) |
diff --git a/roadmap.md b/roadmap.md
index a9c8f5308d..4771802b4f 100644
--- a/roadmap.md
+++ b/roadmap.md
@@ -11,10 +11,12 @@ The Microsoft.Data.SqlClient roadmap communicates project priorities for evolvin
| Milestone | Release Date | Project Board |
|---------------------------|--------------|---------------|
-| Microsoft.Data.SqlClient v1.0 (servicing) | As needed (see also [1.0 releases](https://github.com/dotnet/sqlclient/blob/master/release-notes/1.0)) | Closed |
| Microsoft.Data.SqlClient v1.1 (servicing) | As needed (see also [1.1 releases](https://github.com/dotnet/sqlclient/blob/master/release-notes/1.1)) | Closed |
-| Microsoft.Data.SqlClient v2.0 (servicing) | As needed (see also [2.0 releases](https://github.com/dotnet/sqlclient/blob/master/release-notes/2.0)) | Closed |
-| Microsoft.Data.SqlClient v2.1 | GA (General Availability) estimated for November 2020 | [SqlClient 2.1.0](https://github.com/dotnet/SqlClient/projects/6) |
+| Microsoft.Data.SqlClient v2.1 (servicing) | As needed (see also [2.1 releases](https://github.com/dotnet/sqlclient/blob/master/release-notes/2.1)) | Closed |
+| Microsoft.Data.SqlClient v3.0 (servicing) | As needed (see also [3.0 releases](https://github.com/dotnet/sqlclient/blob/master/release-notes/3.0)) | Closed |
+| Microsoft.Data.SqlClient v4.0 (servicing) | As needed (see also [4.0 releases](https://github.com/dotnet/sqlclient/blob/master/release-notes/4.0)) | Closed |
+| Microsoft.Data.SqlClient v4.1 (servicing) | As needed (see also [4.1 releases](https://github.com/dotnet/sqlclient/blob/master/release-notes/4.1)) | Closed |
+| Microsoft.Data.SqlClient v5.0 | GA (General Availability) estimated for May 2022 | [SqlClient 5.0.0](https://github.com/dotnet/SqlClient/projects/9)
> Note: Dates are calendar year (as opposed to fiscal year).
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index b43e2df35a..afcf503118 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,6 +1,7 @@
+ 9.0truefalsetrue
@@ -19,16 +20,15 @@
************** IMPORTANT NOTE BEFORE PROCEEDING WITH "PACKAGE" AND "NETSTANDARDPACKAGE" REFERENCE TYPES ***************
CREATE A NUGET PACKAGE WITH BELOW COMMAND AND ADD TO LOCAL FOLDER + UPDATE NUGET CONFIG FILE TO READ FROM THAT LOCATION
- > msbuild /p:configuration=Release
+ > msbuild -p:configuration=Release
-->
Project$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
- true
-
+ $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
-
+
@@ -39,11 +39,14 @@
$(MSBuildThisFileDirectory)$(ProjectDir)..\$(RepoRoot)artifacts\$(ReferenceType)\
+ $(Artifacts)tools\$(ProjectDir)Microsoft.Data.SqlClient\
+ $(ProjectDir)Microsoft.SqlServer.Server\$(ManagedSourceCode)netcore\$(ManagedSourceCode)netfx\$(ManagedSourceCode)netfx\src\Resources\$(ManagedSourceCode)add-ons\
+ $(RepoRoot)src\Microsoft.SqlServer.Server\$(Artifacts)obj\$(NetCoreSource)src\Common\src$(NetCoreSource)src\Common\tests
@@ -52,6 +55,7 @@
$(Artifacts)bin\AnyOS\$(Artifacts)bin\Unix\$(RepoRoot)tools\
+ $(ToolsDir)GenAPI\$(RepoRoot)packages\$(RepoRoot).nuget\$(NuGetRoot)nuget.exe
diff --git a/src/Microsoft.Data.SqlClient.sln b/src/Microsoft.Data.SqlClient.sln
index 855baeedaa..c5b34945a0 100644
--- a/src/Microsoft.Data.SqlClient.sln
+++ b/src/Microsoft.Data.SqlClient.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29521.150
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31912.275
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Data.SqlClient", "Microsoft.Data.SqlClient\netfx\src\Microsoft.Data.SqlClient.csproj", "{407890AC-9876-4FEF-A6F1-F36A876BAADE}"
EndProject
@@ -16,6 +16,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TDS", "Microsoft.Data.SqlCl
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.Tests", "Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj", "{D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}"
+ ProjectSection(ProjectDependencies) = postProject
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient", "Microsoft.Data.SqlClient\netcore\src\Microsoft.Data.SqlClient.csproj", "{37431336-5307-4184-9356-C4B7E47DC714}"
EndProject
@@ -26,22 +29,31 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Address", "Microsoft.Data.SqlClient\tests\ManualTests\SQL\UdtTest\UDTs\Address\Address.csproj", "{D1392B54-998A-4F27-BC17-4CE149117BCC}"
ProjectSection(ProjectDependencies) = postProject
{FDA6971D-9F57-4DA4-B10A-261C91684CFC} = {FDA6971D-9F57-4DA4-B10A-261C91684CFC}
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
{407890AC-9876-4FEF-A6F1-F36A876BAADE} = {407890AC-9876-4FEF-A6F1-F36A876BAADE}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.ManualTesting.Tests", "Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj", "{45DB5F86-7AE3-45C6-870D-F9357B66BDB5}"
+ ProjectSection(ProjectDependencies) = postProject
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Circle", "Microsoft.Data.SqlClient\tests\ManualTests\SQL\UdtTest\UDTs\Circle\Circle.csproj", "{6C88F00F-9597-43AD-9E5F-9B344DA3B16F}"
ProjectSection(ProjectDependencies) = postProject
{FDA6971D-9F57-4DA4-B10A-261C91684CFC} = {FDA6971D-9F57-4DA4-B10A-261C91684CFC}
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shapes", "Microsoft.Data.SqlClient\tests\ManualTests\SQL\UdtTest\UDTs\Shapes\Shapes.csproj", "{B73A7063-37C3-415D-AD53-BB3DA20ABD6E}"
ProjectSection(ProjectDependencies) = postProject
{FDA6971D-9F57-4DA4-B10A-261C91684CFC} = {FDA6971D-9F57-4DA4-B10A-261C91684CFC}
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utf8String", "Microsoft.Data.SqlClient\tests\ManualTests\SQL\UdtTest\UDTs\Utf8String\Utf8String.csproj", "{E0A6BB21-574B-43D9-890D-6E1144F2EE9E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{A2E7E470-5EFF-4828-B55E-FCBA3650F51C}"
EndProject
@@ -52,6 +64,11 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient", "Microsoft.Data.SqlClient\netfx\ref\Microsoft.Data.SqlClient.csproj", "{412BCCC8-19F6-489A-B594-E9A506816155}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider", "Microsoft.Data.SqlClient\add-ons\AzureKeyVaultProvider\Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj", "{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
+ {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B} = {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}
+ {412BCCC8-19F6-489A-B594-E9A506816155} = {412BCCC8-19F6-489A-B594-E9A506816155}
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "add-ons", "add-ons", "{C9726AED-D6A3-4AAC-BA04-92DD1F079594}"
EndProject
@@ -103,6 +120,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlClient",
..\doc\snippets\Microsoft.Data.SqlClient\SqlConnection.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnection.xml
..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml
..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionColumnEncryptionSetting.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionColumnEncryptionSetting.xml
+ ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOption.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionEncryptOption.xml
..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionStringBuilder.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionStringBuilder.xml
..\doc\snippets\Microsoft.Data.SqlClient\SqlCredential.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlCredential.xml
..\doc\snippets\Microsoft.Data.SqlClient\SqlDataAdapter.xml = ..\doc\snippets\Microsoft.Data.SqlClient\SqlDataAdapter.xml
@@ -164,80 +182,47 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Data.SqlTypes", "
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.DockerLinuxTest", "Microsoft.Data.SqlClient\tests\DockerLinuxTest\Microsoft.Data.SqlClient.DockerLinuxTest.csproj", "{833157E1-1E53-4908-B4CB-5C5507A44582}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.NSLibrary", "Microsoft.Data.SqlClient\tests\NSLibrary\Microsoft.Data.SqlClient.NSLibrary.csproj", "{E7336BFB-8521-423A-A140-3123F9065C5D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
+ {407890AC-9876-4FEF-A6F1-F36A876BAADE} = {407890AC-9876-4FEF-A6F1-F36A876BAADE}
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.TestUtilities", "Microsoft.Data.SqlClient\tests\tools\Microsoft.Data.SqlClient.TestUtilities\Microsoft.Data.SqlClient.TestUtilities.csproj", "{89D6D382-9B36-43C9-A912-03802FDA8E36}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.ExtUtilities", "Microsoft.Data.SqlClient\tests\tools\Microsoft.Data.SqlClient.ExtUtilities\Microsoft.Data.SqlClient.ExtUtilities.csproj", "{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomRetryLogicProvider", "Microsoft.Data.SqlClient\tests\CustomConfigurableRetryLogic\CustomRetryLogicProvider.csproj", "{B499E477-C9B1-4087-A5CF-5C762D90E433}"
+ ProjectSection(ProjectDependencies) = postProject
+ {37431336-5307-4184-9356-C4B7E47DC714} = {37431336-5307-4184-9356-C4B7E47DC714}
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.DockerLinuxTest", "Microsoft.Data.SqlClient\tests\Docker\DockerLinuxTest\Microsoft.Data.SqlClient.DockerLinuxTest.csproj", "{B93A3149-67E8-491E-A1E5-19D65F9D9E98}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Data.SqlClient.PerformanceTests", "Microsoft.Data.SqlClient\tests\PerformanceTests\Microsoft.Data.SqlClient.PerformanceTests.csproj", "{599A336B-2A5F-473D-8442-1223ED37C93E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4F3CD363-B1E6-4D6D-9466-97D78A56BE45}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SqlServer.Server", "Microsoft.SqlServer.Server\Microsoft.SqlServer.Server.csproj", "{A314812A-7820-4565-A2A8-ABBE391C11E4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
- net46-Debug|Any CPU = net46-Debug|Any CPU
- net46-Debug|x64 = net46-Debug|x64
- net46-Debug|x86 = net46-Debug|x86
- net46-Release|Any CPU = net46-Release|Any CPU
- net46-Release|x64 = net46-Release|x64
- net46-Release|x86 = net46-Release|x86
- netcoreapp2.1-Debug|Any CPU = netcoreapp2.1-Debug|Any CPU
- netcoreapp2.1-Debug|x64 = netcoreapp2.1-Debug|x64
- netcoreapp2.1-Debug|x86 = netcoreapp2.1-Debug|x86
- netcoreapp2.1-Release|Any CPU = netcoreapp2.1-Release|Any CPU
- netcoreapp2.1-Release|x64 = netcoreapp2.1-Release|x64
- netcoreapp2.1-Release|x86 = netcoreapp2.1-Release|x86
- netcoreapp3.1-Debug|Any CPU = netcoreapp3.1-Debug|Any CPU
- netcoreapp3.1-Debug|x64 = netcoreapp3.1-Debug|x64
- netcoreapp3.1-Debug|x86 = netcoreapp3.1-Debug|x86
- netcoreapp3.1-Release|Any CPU = netcoreapp3.1-Release|Any CPU
- netcoreapp3.1-Release|x64 = netcoreapp3.1-Release|x64
- netcoreapp3.1-Release|x86 = netcoreapp3.1-Release|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {407890AC-9876-4FEF-A6F1-F36A876BAADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Debug|x64.ActiveCfg = Debug|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Debug|x64.Build.0 = Debug|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Debug|x86.ActiveCfg = Debug|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Debug|x86.Build.0 = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Debug|x64.ActiveCfg = net46-Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Debug|x64.Build.0 = net46-Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Debug|x86.ActiveCfg = net46-Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Debug|x86.Build.0 = net46-Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Release|x64.ActiveCfg = net46-Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Release|x64.Build.0 = net46-Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Release|x86.ActiveCfg = net46-Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.net46-Release|x86.Build.0 = net46-Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Debug|x64.Build.0 = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Debug|x86.Build.0 = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Release|x64.ActiveCfg = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Release|x64.Build.0 = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Release|x86.ActiveCfg = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp2.1-Release|x86.Build.0 = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Debug|x64.Build.0 = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Debug|x86.Build.0 = Debug|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Release|x64.ActiveCfg = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Release|x64.Build.0 = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Release|x86.ActiveCfg = Release|Any CPU
- {407890AC-9876-4FEF-A6F1-F36A876BAADE}.netcoreapp3.1-Release|x86.Build.0 = Release|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {407890AC-9876-4FEF-A6F1-F36A876BAADE}.Release|Any CPU.Build.0 = Release|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Release|x64.ActiveCfg = Release|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Release|x64.Build.0 = Release|Any CPU
{407890AC-9876-4FEF-A6F1-F36A876BAADE}.Release|x86.ActiveCfg = Release|Any CPU
@@ -248,42 +233,6 @@ Global
{1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.Debug|x64.Build.0 = Debug|Any CPU
{1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.Debug|x86.ActiveCfg = Debug|Any CPU
{1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.Debug|x86.Build.0 = Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Release|x64.Build.0 = net46-Release|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.net46-Release|x86.Build.0 = net46-Release|x86
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.Release|Any CPU.Build.0 = Release|Any CPU
{1FF891B4-D3DE-4CCE-887C-CB48F5351A45}.Release|x64.ActiveCfg = Release|Any CPU
@@ -296,42 +245,6 @@ Global
{978063D3-FBB5-4E10-8C45-67C90BE1B931}.Debug|x64.Build.0 = Debug|Any CPU
{978063D3-FBB5-4E10-8C45-67C90BE1B931}.Debug|x86.ActiveCfg = Debug|Any CPU
{978063D3-FBB5-4E10-8C45-67C90BE1B931}.Debug|x86.Build.0 = Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Release|x64.Build.0 = net46-Release|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.net46-Release|x86.Build.0 = net46-Release|x86
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {978063D3-FBB5-4E10-8C45-67C90BE1B931}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{978063D3-FBB5-4E10-8C45-67C90BE1B931}.Release|Any CPU.ActiveCfg = Release|Any CPU
{978063D3-FBB5-4E10-8C45-67C90BE1B931}.Release|Any CPU.Build.0 = Release|Any CPU
{978063D3-FBB5-4E10-8C45-67C90BE1B931}.Release|x64.ActiveCfg = Release|Any CPU
@@ -344,42 +257,6 @@ Global
{8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.Debug|x64.Build.0 = Debug|Any CPU
{8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.Debug|x86.ActiveCfg = Debug|Any CPU
{8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.Debug|x86.Build.0 = Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Release|x64.Build.0 = net46-Release|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.net46-Release|x86.Build.0 = net46-Release|x86
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.Release|Any CPU.Build.0 = Release|Any CPU
{8DC9D1A0-351B-47BC-A90F-B9DA542550E9}.Release|x64.ActiveCfg = Release|Any CPU
@@ -392,42 +269,6 @@ Global
{D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.Debug|x64.Build.0 = Debug|Any CPU
{D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.Debug|x86.ActiveCfg = Debug|Any CPU
{D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.Debug|x86.Build.0 = Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Release|x64.Build.0 = net46-Release|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.net46-Release|x86.Build.0 = net46-Release|x86
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.Release|Any CPU.Build.0 = Release|Any CPU
{D2D1E2D1-B6E0-489F-A36D-1F3047AB87B9}.Release|x64.ActiveCfg = Release|Any CPU
@@ -440,36 +281,6 @@ Global
{37431336-5307-4184-9356-C4B7E47DC714}.Debug|x64.Build.0 = Debug|Any CPU
{37431336-5307-4184-9356-C4B7E47DC714}.Debug|x86.ActiveCfg = Debug|Any CPU
{37431336-5307-4184-9356-C4B7E47DC714}.Debug|x86.Build.0 = Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.net46-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.net46-Debug|x64.ActiveCfg = Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.net46-Debug|x86.ActiveCfg = Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.net46-Release|Any CPU.ActiveCfg = Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.net46-Release|x64.ActiveCfg = Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.net46-Release|x86.ActiveCfg = Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {37431336-5307-4184-9356-C4B7E47DC714}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{37431336-5307-4184-9356-C4B7E47DC714}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37431336-5307-4184-9356-C4B7E47DC714}.Release|Any CPU.Build.0 = Release|Any CPU
{37431336-5307-4184-9356-C4B7E47DC714}.Release|x64.ActiveCfg = Release|Any CPU
@@ -482,42 +293,6 @@ Global
{D1392B54-998A-4F27-BC17-4CE149117BCC}.Debug|x64.Build.0 = Debug|Any CPU
{D1392B54-998A-4F27-BC17-4CE149117BCC}.Debug|x86.ActiveCfg = Debug|Any CPU
{D1392B54-998A-4F27-BC17-4CE149117BCC}.Debug|x86.Build.0 = Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Release|x64.Build.0 = net46-Release|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.net46-Release|x86.Build.0 = net46-Release|x86
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {D1392B54-998A-4F27-BC17-4CE149117BCC}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{D1392B54-998A-4F27-BC17-4CE149117BCC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1392B54-998A-4F27-BC17-4CE149117BCC}.Release|Any CPU.Build.0 = Release|Any CPU
{D1392B54-998A-4F27-BC17-4CE149117BCC}.Release|x64.ActiveCfg = Release|Any CPU
@@ -530,42 +305,6 @@ Global
{45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.Debug|x64.Build.0 = Debug|Any CPU
{45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.Debug|x86.ActiveCfg = Debug|Any CPU
{45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.Debug|x86.Build.0 = Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Release|x64.Build.0 = net46-Release|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.net46-Release|x86.Build.0 = net46-Release|x86
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.Release|Any CPU.Build.0 = Release|Any CPU
{45DB5F86-7AE3-45C6-870D-F9357B66BDB5}.Release|x64.ActiveCfg = Release|Any CPU
@@ -578,42 +317,6 @@ Global
{6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.Debug|x64.Build.0 = Debug|Any CPU
{6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.Debug|x86.ActiveCfg = Debug|Any CPU
{6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.Debug|x86.Build.0 = Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Release|x64.Build.0 = net46-Release|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.net46-Release|x86.Build.0 = net46-Release|x86
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.Release|Any CPU.Build.0 = Release|Any CPU
{6C88F00F-9597-43AD-9E5F-9B344DA3B16F}.Release|x64.ActiveCfg = Release|Any CPU
@@ -626,42 +329,6 @@ Global
{B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.Debug|x64.Build.0 = Debug|Any CPU
{B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.Debug|x86.ActiveCfg = Debug|Any CPU
{B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.Debug|x86.Build.0 = Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Release|x64.Build.0 = net46-Release|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.net46-Release|x86.Build.0 = net46-Release|x86
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.Release|Any CPU.Build.0 = Release|Any CPU
{B73A7063-37C3-415D-AD53-BB3DA20ABD6E}.Release|x64.ActiveCfg = Release|Any CPU
@@ -674,42 +341,6 @@ Global
{E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.Debug|x64.Build.0 = Debug|Any CPU
{E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.Debug|x86.ActiveCfg = Debug|Any CPU
{E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.Debug|x86.Build.0 = Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Release|x64.Build.0 = net46-Release|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.net46-Release|x86.Build.0 = net46-Release|x86
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.Release|Any CPU.Build.0 = Release|Any CPU
{E0A6BB21-574B-43D9-890D-6E1144F2EE9E}.Release|x64.ActiveCfg = Release|Any CPU
@@ -722,36 +353,6 @@ Global
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Debug|x64.Build.0 = Debug|Any CPU
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Debug|x86.ActiveCfg = Debug|Any CPU
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Debug|x86.Build.0 = Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.net46-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.net46-Debug|x64.ActiveCfg = Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.net46-Debug|x86.ActiveCfg = Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.net46-Release|Any CPU.ActiveCfg = Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.net46-Release|x64.ActiveCfg = Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.net46-Release|x86.ActiveCfg = Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Release|Any CPU.Build.0 = Release|Any CPU
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Release|x64.ActiveCfg = Release|Any CPU
@@ -759,39 +360,13 @@ Global
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Release|x86.ActiveCfg = Release|Any CPU
{1C9FC4B8-54BC-4B6C-BB3A-F5CD59D80A9B}.Release|x86.Build.0 = Release|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {412BCCC8-19F6-489A-B594-E9A506816155}.Debug|Any CPU.Build.0 = Debug|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Debug|x64.ActiveCfg = Debug|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Debug|x64.Build.0 = Debug|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Debug|x86.ActiveCfg = Debug|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Debug|x86.Build.0 = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Debug|x64.ActiveCfg = net46-Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Debug|x64.Build.0 = net46-Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Debug|x86.ActiveCfg = net46-Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Debug|x86.Build.0 = net46-Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Release|x64.ActiveCfg = net46-Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Release|x64.Build.0 = net46-Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Release|x86.ActiveCfg = net46-Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.net46-Release|x86.Build.0 = net46-Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp2.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp2.1-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp2.1-Release|x64.ActiveCfg = Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp2.1-Release|x86.ActiveCfg = Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Debug|x64.Build.0 = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Debug|x86.Build.0 = Debug|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Release|x64.ActiveCfg = Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Release|x64.Build.0 = Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Release|x86.ActiveCfg = Release|Any CPU
- {412BCCC8-19F6-489A-B594-E9A506816155}.netcoreapp3.1-Release|x86.Build.0 = Release|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {412BCCC8-19F6-489A-B594-E9A506816155}.Release|Any CPU.Build.0 = Release|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Release|x64.ActiveCfg = Release|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Release|x64.Build.0 = Release|Any CPU
{412BCCC8-19F6-489A-B594-E9A506816155}.Release|x86.ActiveCfg = Release|Any CPU
@@ -802,42 +377,6 @@ Global
{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.Debug|x64.Build.0 = Debug|Any CPU
{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.Debug|x86.ActiveCfg = Debug|Any CPU
{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.Debug|x86.Build.0 = Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Release|x64.ActiveCfg = net46-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Release|x64.Build.0 = net46-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Release|x86.ActiveCfg = net46-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.net46-Release|x86.Build.0 = net46-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Debug|x64.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Debug|x64.Build.0 = netcoreapp2.1-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Release|x64.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Release|x64.Build.0 = netcoreapp2.1-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Release|x86.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp2.1-Release|x86.Build.0 = netcoreapp2.1-Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Release|Any CPU.Build.0 = Release|Any CPU
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.Release|Any CPU.Build.0 = Release|Any CPU
{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}.Release|x64.ActiveCfg = Release|Any CPU
@@ -850,42 +389,6 @@ Global
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Debug|x64.Build.0 = Debug|Any CPU
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Debug|x86.ActiveCfg = Debug|Any CPU
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Debug|x86.Build.0 = Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Debug|Any CPU.ActiveCfg = net46-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Debug|Any CPU.Build.0 = net46-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Debug|x64.ActiveCfg = net46-Debug|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Debug|x64.Build.0 = net46-Debug|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Debug|x86.ActiveCfg = net46-Debug|x86
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Debug|x86.Build.0 = net46-Debug|x86
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Release|Any CPU.ActiveCfg = net46-Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Release|Any CPU.Build.0 = net46-Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Release|x64.ActiveCfg = net46-Release|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Release|x64.Build.0 = net46-Release|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Release|x86.ActiveCfg = net46-Release|x86
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.net46-Release|x86.Build.0 = net46-Release|x86
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Debug|Any CPU.Build.0 = netcoreapp2.1-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Debug|x64.Build.0 = Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Debug|x86.ActiveCfg = netcoreapp2.1-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Debug|x86.Build.0 = netcoreapp2.1-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Release|Any CPU.ActiveCfg = netcoreapp2.1-Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Release|Any CPU.Build.0 = netcoreapp2.1-Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Release|x64.ActiveCfg = Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Release|x64.Build.0 = Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Release|x86.ActiveCfg = Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp2.1-Release|x86.Build.0 = Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = netcoreapp3.1-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Debug|Any CPU.Build.0 = netcoreapp3.1-Debug|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Debug|x64.ActiveCfg = netcoreapp3.1-Debug|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Debug|x64.Build.0 = netcoreapp3.1-Debug|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Debug|x86.ActiveCfg = netcoreapp3.1-Debug|x86
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Debug|x86.Build.0 = netcoreapp3.1-Debug|x86
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Release|Any CPU.ActiveCfg = netcoreapp3.1-Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Release|Any CPU.Build.0 = netcoreapp3.1-Release|Any CPU
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Release|x64.ActiveCfg = netcoreapp3.1-Release|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Release|x64.Build.0 = netcoreapp3.1-Release|x64
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Release|x86.ActiveCfg = netcoreapp3.1-Release|x86
- {FDA6971D-9F57-4DA4-B10A-261C91684CFC}.netcoreapp3.1-Release|x86.Build.0 = netcoreapp3.1-Release|x86
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Release|Any CPU.Build.0 = Release|Any CPU
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Release|x64.ActiveCfg = Release|Any CPU
@@ -893,143 +396,21 @@ Global
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Release|x86.ActiveCfg = Release|Any CPU
{FDA6971D-9F57-4DA4-B10A-261C91684CFC}.Release|x86.Build.0 = Release|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Debug|x64.ActiveCfg = Debug|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Debug|x64.Build.0 = Debug|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Debug|x86.ActiveCfg = Debug|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Debug|x86.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Debug|Any CPU.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Debug|x64.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Debug|x64.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Debug|x86.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Debug|x86.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Release|Any CPU.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Release|Any CPU.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Release|x64.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Release|x64.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Release|x86.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.net46-Release|x86.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Debug|x64.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Debug|x86.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Release|Any CPU.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Release|x64.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Release|x64.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Release|x86.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp2.1-Release|x86.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Debug|x64.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Debug|x86.Build.0 = Debug|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Release|Any CPU.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Release|x64.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Release|x64.Build.0 = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Release|x86.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.netcoreapp3.1-Release|x86.Build.0 = Release|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|Any CPU.Build.0 = Release|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|x64.ActiveCfg = Release|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|x64.Build.0 = Release|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|x86.ActiveCfg = Release|Any CPU
{F5DF2FDC-C860-4CB3-8B24-7C903C6FC076}.Release|x86.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Debug|x64.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Debug|x64.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Debug|x86.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Debug|x86.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Debug|Any CPU.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Debug|x64.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Debug|x64.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Debug|x86.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Debug|x86.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Release|Any CPU.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Release|Any CPU.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Release|x64.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Release|x64.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Release|x86.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.net46-Release|x86.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Debug|x64.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Debug|x86.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Release|Any CPU.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Release|x64.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Release|x64.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Release|x86.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp2.1-Release|x86.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Debug|x64.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Debug|x86.Build.0 = Debug|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Release|Any CPU.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Release|x64.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Release|x64.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Release|x86.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.netcoreapp3.1-Release|x86.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Release|Any CPU.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Release|x64.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Release|x64.Build.0 = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Release|x86.ActiveCfg = Release|Any CPU
- {833157E1-1E53-4908-B4CB-5C5507A44582}.Release|x86.Build.0 = Release|Any CPU
{E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x64.ActiveCfg = Debug|x64
{E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x64.Build.0 = Debug|x64
{E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x86.ActiveCfg = Debug|x86
{E7336BFB-8521-423A-A140-3123F9065C5D}.Debug|x86.Build.0 = Debug|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Debug|Any CPU.Build.0 = Debug|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Debug|x64.ActiveCfg = Debug|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Debug|x64.Build.0 = Debug|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Debug|x86.ActiveCfg = Debug|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Debug|x86.Build.0 = Debug|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Release|Any CPU.ActiveCfg = Release|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Release|Any CPU.Build.0 = Release|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Release|x64.ActiveCfg = Release|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Release|x64.Build.0 = Release|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Release|x86.ActiveCfg = Release|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.net46-Release|x86.Build.0 = Release|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Debug|x64.Build.0 = Debug|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Debug|x86.ActiveCfg = Debug|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Debug|x86.Build.0 = Debug|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Release|Any CPU.Build.0 = Release|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Release|x64.ActiveCfg = Release|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Release|x64.Build.0 = Release|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Release|x86.ActiveCfg = Release|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp2.1-Release|x86.Build.0 = Release|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Debug|x64.ActiveCfg = Debug|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Debug|x64.Build.0 = Debug|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Debug|x86.ActiveCfg = Debug|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Debug|x86.Build.0 = Debug|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Release|Any CPU.Build.0 = Release|Any CPU
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Release|x64.ActiveCfg = Release|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Release|x64.Build.0 = Release|x64
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Release|x86.ActiveCfg = Release|x86
- {E7336BFB-8521-423A-A140-3123F9065C5D}.netcoreapp3.1-Release|x86.Build.0 = Release|x86
{E7336BFB-8521-423A-A140-3123F9065C5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7336BFB-8521-423A-A140-3123F9065C5D}.Release|Any CPU.Build.0 = Release|Any CPU
{E7336BFB-8521-423A-A140-3123F9065C5D}.Release|x64.ActiveCfg = Release|x64
@@ -1042,42 +423,6 @@ Global
{89D6D382-9B36-43C9-A912-03802FDA8E36}.Debug|x64.Build.0 = Debug|Any CPU
{89D6D382-9B36-43C9-A912-03802FDA8E36}.Debug|x86.ActiveCfg = Debug|Any CPU
{89D6D382-9B36-43C9-A912-03802FDA8E36}.Debug|x86.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Debug|Any CPU.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Debug|x64.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Debug|x64.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Debug|x86.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Debug|x86.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Release|Any CPU.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Release|Any CPU.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Release|x64.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Release|x64.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Release|x86.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.net46-Release|x86.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Debug|x64.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Debug|x86.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Release|Any CPU.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Release|x64.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Release|x64.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Release|x86.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp2.1-Release|x86.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Debug|x64.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Debug|x86.Build.0 = Debug|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Release|Any CPU.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Release|x64.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Release|x64.Build.0 = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Release|x86.ActiveCfg = Release|Any CPU
- {89D6D382-9B36-43C9-A912-03802FDA8E36}.netcoreapp3.1-Release|x86.Build.0 = Release|Any CPU
{89D6D382-9B36-43C9-A912-03802FDA8E36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89D6D382-9B36-43C9-A912-03802FDA8E36}.Release|Any CPU.Build.0 = Release|Any CPU
{89D6D382-9B36-43C9-A912-03802FDA8E36}.Release|x64.ActiveCfg = Release|Any CPU
@@ -1090,48 +435,60 @@ Global
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Debug|x64.Build.0 = Debug|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Debug|x86.ActiveCfg = Debug|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Debug|x86.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Debug|Any CPU.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Debug|x64.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Debug|x64.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Debug|x86.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Debug|x86.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Release|Any CPU.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Release|Any CPU.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Release|x64.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Release|x64.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Release|x86.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.net46-Release|x86.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Debug|x64.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Debug|x86.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Release|Any CPU.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Release|x64.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Release|x64.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Release|x86.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp2.1-Release|x86.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Debug|Any CPU.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Debug|x64.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Debug|x64.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Debug|x86.ActiveCfg = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Debug|x86.Build.0 = Debug|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Release|Any CPU.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Release|Any CPU.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Release|x64.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Release|x64.Build.0 = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Release|x86.ActiveCfg = Release|Any CPU
- {E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.netcoreapp3.1-Release|x86.Build.0 = Release|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Release|Any CPU.Build.0 = Release|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Release|x64.ActiveCfg = Release|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Release|x64.Build.0 = Release|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Release|x86.ActiveCfg = Release|Any CPU
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B}.Release|x86.Build.0 = Release|Any CPU
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Debug|x64.ActiveCfg = Debug|x64
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Debug|x64.Build.0 = Debug|x64
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Debug|x86.ActiveCfg = Debug|x86
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Debug|x86.Build.0 = Debug|x86
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Release|x64.ActiveCfg = Release|x64
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Release|x64.Build.0 = Release|x64
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Release|x86.ActiveCfg = Release|x86
+ {B499E477-C9B1-4087-A5CF-5C762D90E433}.Release|x86.Build.0 = Release|x86
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Debug|x64.Build.0 = Debug|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Debug|x86.Build.0 = Debug|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Release|x64.ActiveCfg = Release|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Release|x64.Build.0 = Release|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Release|x86.ActiveCfg = Release|Any CPU
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98}.Release|x86.Build.0 = Release|Any CPU
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Debug|x64.ActiveCfg = Debug|x64
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Debug|x64.Build.0 = Debug|x64
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Debug|x86.ActiveCfg = Debug|x86
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Debug|x86.Build.0 = Debug|x86
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Release|x64.ActiveCfg = Release|x64
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Release|x64.Build.0 = Release|x64
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Release|x86.ActiveCfg = Release|x86
+ {599A336B-2A5F-473D-8442-1223ED37C93E}.Release|x86.Build.0 = Release|x86
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Debug|x64.Build.0 = Debug|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Debug|x86.Build.0 = Debug|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Release|x64.ActiveCfg = Release|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Release|x64.Build.0 = Release|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Release|x86.ActiveCfg = Release|Any CPU
+ {A314812A-7820-4565-A2A8-ABBE391C11E4}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1161,10 +518,13 @@ Global
{5D1F0032-7B0D-4FB6-A969-FCFB25C9EA1D} = {71F356DC-DFA3-4163-8BFE-D268722CE189}
{650EB7FA-EB0D-4F8E-AB2C-161C3AD8E363} = {71F356DC-DFA3-4163-8BFE-D268722CE189}
{5A7600BD-AED8-44AB-8F2A-7CB33A8D9C02} = {71F356DC-DFA3-4163-8BFE-D268722CE189}
- {833157E1-1E53-4908-B4CB-5C5507A44582} = {0CC4817A-12F3-4357-912C-09315FAAD008}
{E7336BFB-8521-423A-A140-3123F9065C5D} = {0CC4817A-12F3-4357-912C-09315FAAD008}
{89D6D382-9B36-43C9-A912-03802FDA8E36} = {0CC4817A-12F3-4357-912C-09315FAAD008}
{E4C08DCE-DC29-4FEB-B655-1E7287DB5A2B} = {0CC4817A-12F3-4357-912C-09315FAAD008}
+ {B499E477-C9B1-4087-A5CF-5C762D90E433} = {0CC4817A-12F3-4357-912C-09315FAAD008}
+ {B93A3149-67E8-491E-A1E5-19D65F9D9E98} = {0CC4817A-12F3-4357-912C-09315FAAD008}
+ {599A336B-2A5F-473D-8442-1223ED37C93E} = {0CC4817A-12F3-4357-912C-09315FAAD008}
+ {A314812A-7820-4565-A2A8-ABBE391C11E4} = {4F3CD363-B1E6-4D6D-9466-97D78A56BE45}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01D48116-37A2-4D33-B9EC-94793C702431}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AKVEventSource.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AKVEventSource.cs
new file mode 100644
index 0000000000..085232af78
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AKVEventSource.cs
@@ -0,0 +1,127 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Tracing;
+using System.Threading;
+
+namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+{
+ [EventSource(Name = "Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.EventSource")]
+ internal class AKVEventSource : EventSource
+ {
+ // Defines the singleton instance for the Resources ETW provider
+ public static AKVEventSource Log = new();
+
+ private AKVEventSource() { }
+
+ // Initialized static Scope IDs
+ private static long s_nextScopeId = 0;
+
+ // Provides Correlation Manager Activity Id for current scope.
+ private static Guid GetCorrelationActivityId()
+ {
+ if (Trace.CorrelationManager.ActivityId == Guid.Empty)
+ {
+ Trace.CorrelationManager.ActivityId = Guid.NewGuid();
+ }
+ return Trace.CorrelationManager.ActivityId;
+ }
+
+ #region Keywords
+ public class Keywords
+ {
+ ///
+ /// Captures basic application flow trace events.
+ ///
+ internal const EventKeywords Trace = (EventKeywords)1;
+
+ ///
+ /// Captures basic application scope entering and exiting events.
+ ///
+ internal const EventKeywords Scope = (EventKeywords)2;
+ }
+ #endregion
+
+ #region Tasks
+ ///
+ /// Tasks supported by AKV Provider's EventSource implementation
+ ///
+ public class Tasks
+ {
+ ///
+ /// Task that tracks trace scope.
+ ///
+ public const EventTask Scope = (EventTask)1;
+ }
+ #endregion
+
+ [NonEvent]
+ internal bool IsTraceEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Trace);
+
+ [NonEvent]
+ internal bool IsScopeEnabled() => Log.IsEnabled(EventLevel.Informational, Keywords.Scope);
+
+ #region Event Methods
+ [NonEvent]
+ internal void TryTraceEvent(string message, object p1 = null, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
+ {
+ if (IsTraceEnabled())
+ {
+ WriteTrace(string.Format("Caller: {0}, Message: {1}", memberName,
+ p1 == null ? message :
+ string.Format(message, p1.ToString().Length > 10 ?
+ p1.ToString().Substring(0, 10) + "..." : p1)));
+ }
+ }
+ [NonEvent]
+ internal long TryScopeEnterEvent(string memberName)
+ {
+ if (IsScopeEnabled())
+ {
+ return ScopeEnter(memberName);
+ }
+ return default;
+ }
+ [NonEvent]
+ internal void TryScopeExitEvent(long scopeId)
+ {
+ if (Log.IsScopeEnabled())
+ {
+ ScopeExit(scopeId);
+ }
+ }
+ #endregion
+
+ #region Write Events
+ [Event(1, Level = EventLevel.Informational, Keywords = Keywords.Trace)]
+ internal void WriteTrace(string message) => WriteEvent(1, message);
+
+ [Event(2, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Start, Keywords = Keywords.Scope)]
+ internal long ScopeEnter(string caller)
+ {
+ SetCurrentThreadActivityId(GetCorrelationActivityId());
+ long scopeId = Interlocked.Increment(ref s_nextScopeId);
+ WriteEvent(2, string.Format("Entered Scope: {0}, Caller: {1}", scopeId, caller));
+ return scopeId;
+ }
+
+ [Event(3, Level = EventLevel.Informational, Task = Tasks.Scope, Opcode = EventOpcode.Stop, Keywords = Keywords.Scope)]
+ internal void ScopeExit(long scopeId) => WriteEvent(3, scopeId);
+ #endregion
+ }
+
+ internal readonly struct AKVScope : IDisposable
+ {
+ private readonly long _scopeId;
+
+ public AKVScope(long scopeID) => _scopeId = scopeID;
+ public void Dispose() =>
+ AKVEventSource.Log.TryScopeExitEvent(_scopeId);
+
+ public static AKVScope Create([System.Runtime.CompilerServices.CallerMemberName] string memberName = "") =>
+ new(AKVEventSource.Log.TryScopeEnterEvent(memberName));
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AzureSqlKeyCryptographer.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AzureSqlKeyCryptographer.cs
new file mode 100644
index 0000000000..0dff6ac786
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/AzureSqlKeyCryptographer.cs
@@ -0,0 +1,228 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Azure.Core;
+using Azure.Security.KeyVault.Keys;
+using Azure.Security.KeyVault.Keys.Cryptography;
+using System;
+using System.Collections.Concurrent;
+using System.Threading.Tasks;
+using static Azure.Security.KeyVault.Keys.Cryptography.SignatureAlgorithm;
+
+namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+{
+ internal class AzureSqlKeyCryptographer
+ {
+ ///
+ /// TokenCredential to be used with the KeyClient
+ ///
+ private TokenCredential TokenCredential { get; set; }
+
+ ///
+ /// A mapping of the KeyClient objects to the corresponding Azure Key Vault URI
+ ///
+ private readonly ConcurrentDictionary _keyClientDictionary = new();
+
+ ///
+ /// Holds references to the fetch key tasks and maps them to their corresponding Azure Key Vault Key Identifier (URI).
+ /// These tasks will be used for returning the key in the event that the fetch task has not finished depositing the
+ /// key into the key dictionary.
+ ///
+ private readonly ConcurrentDictionary>> _keyFetchTaskDictionary = new();
+
+ ///
+ /// Holds references to the Azure Key Vault keys and maps them to their corresponding Azure Key Vault Key Identifier (URI).
+ ///
+ private readonly ConcurrentDictionary _keyDictionary = new();
+
+ ///
+ /// Holds references to the Azure Key Vault CryptographyClient objects and maps them to their corresponding Azure Key Vault Key Identifier (URI).
+ ///
+ private readonly ConcurrentDictionary _cryptoClientDictionary = new();
+
+ ///
+ /// Constructs a new KeyCryptographer
+ ///
+ ///
+ internal AzureSqlKeyCryptographer(TokenCredential tokenCredential)
+ {
+ TokenCredential = tokenCredential;
+ }
+
+ ///
+ /// Adds the key, specified by the Key Identifier URI, to the cache.
+ ///
+ ///
+ internal void AddKey(string keyIdentifierUri)
+ {
+ if (TheKeyHasNotBeenCached(keyIdentifierUri))
+ {
+ ParseAKVPath(keyIdentifierUri, out Uri vaultUri, out string keyName, out string keyVersion);
+ CreateKeyClient(vaultUri);
+ FetchKey(vaultUri, keyName, keyVersion, keyIdentifierUri);
+ }
+
+ bool TheKeyHasNotBeenCached(string k) => !_keyDictionary.ContainsKey(k) && !_keyFetchTaskDictionary.ContainsKey(k);
+ }
+
+ ///
+ /// Returns the key specified by the Key Identifier URI
+ ///
+ ///
+ ///
+ internal KeyVaultKey GetKey(string keyIdentifierUri)
+ {
+ if (_keyDictionary.TryGetValue(keyIdentifierUri, out KeyVaultKey key))
+ {
+ AKVEventSource.Log.TryTraceEvent("Fetched master key from cache");
+ return key;
+ }
+
+ if (_keyFetchTaskDictionary.TryGetValue(keyIdentifierUri, out Task> task))
+ {
+ AKVEventSource.Log.TryTraceEvent("New Master key fetched.");
+ return Task.Run(() => task).GetAwaiter().GetResult();
+ }
+
+ // Not a public exception - not likely to occur.
+ AKVEventSource.Log.TryTraceEvent("Master key not found.");
+ throw ADP.MasterKeyNotFound(keyIdentifierUri);
+ }
+
+ ///
+ /// Gets the public Key size in bytes.
+ ///
+ /// The key vault key identifier URI
+ ///
+ internal int GetKeySize(string keyIdentifierUri)
+ {
+ return GetKey(keyIdentifierUri).Key.N.Length;
+ }
+
+ ///
+ /// Generates signature based on RSA PKCS#v1.5 scheme using a specified Azure Key Vault Key URL.
+ ///
+ /// The data to sign
+ /// The key vault key identifier URI
+ ///
+ internal byte[] SignData(byte[] message, string keyIdentifierUri)
+ {
+ CryptographyClient cryptographyClient = GetCryptographyClient(keyIdentifierUri);
+ return cryptographyClient.SignData(RS256, message).Signature;
+ }
+
+ internal bool VerifyData(byte[] message, byte[] signature, string keyIdentifierUri)
+ {
+ CryptographyClient cryptographyClient = GetCryptographyClient(keyIdentifierUri);
+ AKVEventSource.Log.TryTraceEvent("Sending request to verify data");
+ return cryptographyClient.VerifyData(RS256, message, signature).IsValid;
+ }
+
+ internal byte[] UnwrapKey(KeyWrapAlgorithm keyWrapAlgorithm, byte[] encryptedKey, string keyIdentifierUri)
+ {
+ CryptographyClient cryptographyClient = GetCryptographyClient(keyIdentifierUri);
+ AKVEventSource.Log.TryTraceEvent("Sending request to unwrap key.");
+ return cryptographyClient.UnwrapKey(keyWrapAlgorithm, encryptedKey).Key;
+ }
+
+ internal byte[] WrapKey(KeyWrapAlgorithm keyWrapAlgorithm, byte[] key, string keyIdentifierUri)
+ {
+ CryptographyClient cryptographyClient = GetCryptographyClient(keyIdentifierUri);
+ AKVEventSource.Log.TryTraceEvent("Sending request to wrap key.");
+ return cryptographyClient.WrapKey(keyWrapAlgorithm, key).EncryptedKey;
+ }
+
+ private CryptographyClient GetCryptographyClient(string keyIdentifierUri)
+ {
+ if (_cryptoClientDictionary.TryGetValue(keyIdentifierUri, out CryptographyClient client))
+ {
+ return client;
+ }
+
+ CryptographyClient cryptographyClient = new(GetKey(keyIdentifierUri).Id, TokenCredential);
+ _cryptoClientDictionary.TryAdd(keyIdentifierUri, cryptographyClient);
+
+ return cryptographyClient;
+ }
+
+ ///
+ ///
+ ///
+ /// The Azure Key Vault URI
+ /// The name of the Azure Key Vault key
+ /// The version of the Azure Key Vault key
+ /// The Azure Key Vault key identifier
+ private void FetchKey(Uri vaultUri, string keyName, string keyVersion, string keyResourceUri)
+ {
+ Task> fetchKeyTask = FetchKeyFromKeyVault(vaultUri, keyName, keyVersion);
+ _keyFetchTaskDictionary.AddOrUpdate(keyResourceUri, fetchKeyTask, (k, v) => fetchKeyTask);
+
+ fetchKeyTask
+ .ContinueWith(k => ValidateRsaKey(k.GetAwaiter().GetResult()))
+ .ContinueWith(k => _keyDictionary.AddOrUpdate(keyResourceUri, k.GetAwaiter().GetResult(), (key, v) => k.GetAwaiter().GetResult()));
+
+ Task.Run(() => fetchKeyTask);
+ }
+
+ ///
+ /// Looks up the KeyClient object by it's URI and then fetches the key by name.
+ ///
+ /// The Azure Key Vault URI
+ /// Then name of the key
+ /// Then version of the key
+ ///
+ private Task> FetchKeyFromKeyVault(Uri vaultUri, string keyName, string keyVersion)
+ {
+ _keyClientDictionary.TryGetValue(vaultUri, out KeyClient keyClient);
+ AKVEventSource.Log.TryTraceEvent("Fetching requested master key: {0}", keyName);
+ return keyClient?.GetKeyAsync(keyName, keyVersion);
+ }
+
+ ///
+ /// Validates that a key is of type RSA
+ ///
+ ///
+ ///
+ private KeyVaultKey ValidateRsaKey(KeyVaultKey key)
+ {
+ if (key.KeyType != KeyType.Rsa && key.KeyType != KeyType.RsaHsm)
+ {
+ AKVEventSource.Log.TryTraceEvent("Non-RSA KeyType received: {0}", key.KeyType);
+ throw ADP.NonRsaKeyFormat(key.KeyType.ToString());
+ }
+
+ return key;
+ }
+
+ ///
+ /// Instantiates and adds a KeyClient to the KeyClient dictionary
+ ///
+ /// The Azure Key Vault URI
+ private void CreateKeyClient(Uri vaultUri)
+ {
+ if (!_keyClientDictionary.ContainsKey(vaultUri))
+ {
+ _keyClientDictionary.TryAdd(vaultUri, new KeyClient(vaultUri, TokenCredential));
+ }
+ }
+
+ ///
+ /// Validates and parses the Azure Key Vault URI and key name.
+ ///
+ /// The Azure Key Vault key identifier
+ /// The Azure Key Vault URI
+ /// The name of the key
+ /// The version of the key
+ private void ParseAKVPath(string masterKeyPath, out Uri vaultUri, out string masterKeyName, out string masterKeyVersion)
+ {
+ Uri masterKeyPathUri = new(masterKeyPath);
+ vaultUri = new Uri(masterKeyPathUri.GetLeftPart(UriPartial.Authority));
+ masterKeyName = masterKeyPathUri.Segments[2];
+ masterKeyVersion = masterKeyPathUri.Segments.Length > 3 ? masterKeyPathUri.Segments[3] : null;
+
+ AKVEventSource.Log.TryTraceEvent("Received Key Name: {0}", masterKeyName);
+ AKVEventSource.Log.TryTraceEvent("Received Key Version: {0}", masterKeyVersion);
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Constants.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Constants.cs
index a75101669f..6e26ac8539 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Constants.cs
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Constants.cs
@@ -2,21 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
{
internal static class Constants
{
- ///
- /// Hashing algorithm used for signing
- ///
- internal const string HashingAlgorithm = @"RS256";
-
///
/// Azure Key Vault Domain Name
///
@@ -32,7 +21,7 @@ internal static class Constants
};
///
- /// Always Encrypted Param names for exec handling
+ /// Always Encrypted Parameter names for exec handling
///
internal const string AeParamColumnEncryptionKey = "columnEncryptionKey";
internal const string AeParamEncryptionAlgorithm = "encryptionAlgorithm";
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/LocalCache.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/LocalCache.cs
new file mode 100644
index 0000000000..3e17f5d951
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/LocalCache.cs
@@ -0,0 +1,103 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Extensions.Caching.Memory;
+using System;
+using static System.Math;
+
+namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+{
+ ///
+ /// LocalCache is to reuse heavy objects.
+ /// When performing a heavy creation operation, we will save the result in our cache container.
+ /// The next time that we need that result, we will pull it from the cache container, instead of performing the heavy operation again.
+ /// It is used for decrypting CEKs and verifying CMK metadata. Encrypted CEKs and signatures are different every time, even
+ /// when done with the same key, and should not be cached.
+ ///
+ internal class LocalCache
+ {
+ ///
+ /// A simple thread-safe implementation of an in-memory Cache.
+ /// When the process dies, the cache dies with it.
+ ///
+ private readonly MemoryCache _cache;
+
+ private readonly int _maxSize;
+
+ ///
+ /// Sets an absolute expiration time, relative to now.
+ ///
+ internal TimeSpan? TimeToLive { get; set; }
+
+ ///
+ /// Gets the count of the current entries for diagnostic purposes.
+ ///
+ internal int Count => _cache.Count;
+
+ ///
+ /// Constructs a new LocalCache object.
+ ///
+ internal LocalCache(int maxSizeLimit = int.MaxValue)
+ {
+ if (maxSizeLimit <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(maxSizeLimit));
+ }
+
+ _maxSize = maxSizeLimit;
+ _cache = new MemoryCache(new MemoryCacheOptions());
+ }
+
+ ///
+ /// Looks for the cache entry that maps to the value. If it exists (cache hit) it will simply be
+ /// returned. Otherwise, the delegate function will be invoked to create the value.
+ /// It will then get stored it in the cache and set the time-to-live before getting returned.
+ ///
+ /// The key for the cache entry.
+ /// The delegate function that will create the cache entry if it does not exist.
+ /// The cache entry.
+ internal TValue GetOrCreate(TKey key, Func createItem)
+ {
+ if (TimeToLive <= TimeSpan.Zero)
+ {
+ AKVEventSource.Log.TryTraceEvent("Key caching found disabled, fetching key information.");
+ return createItem();
+ }
+
+ if (!_cache.TryGetValue(key, out TValue cacheEntry))
+ {
+ AKVEventSource.Log.TryTraceEvent("Cached entry not found, creating new entry.");
+ if (_cache.Count == _maxSize)
+ {
+ _cache.Compact(Max(0.10, 1.0 / _maxSize));
+ }
+
+ cacheEntry = createItem();
+ var cacheEntryOptions = new MemoryCacheEntryOptions
+ {
+ AbsoluteExpirationRelativeToNow = TimeToLive
+ };
+
+ _cache.Set(key, cacheEntry, cacheEntryOptions);
+ AKVEventSource.Log.TryTraceEvent("Entry added to local cache.");
+ }
+ else
+ {
+ AKVEventSource.Log.TryTraceEvent("Cached entry found.");
+ }
+
+ return cacheEntry;
+ }
+
+ ///
+ /// Determines whether the LocalCache contains the specified key.
+ ///
+ ///
+ ///
+ internal bool Contains(TKey key)
+ {
+ return _cache.TryGetValue(key, out _);
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
index b882eb77b7..3f2267451e 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.csproj
@@ -4,9 +4,9 @@
Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProviderAzureKeyVaultProvider{9073ABEF-92E0-4702-BB23-2C99CEF9BDD7}
- netcoreapp
- netfx
- Debug;Release;net46-Release;net46-Debug;netcoreapp2.1-Debug;netcoreapp2.1-Release;netcoreapp3.1-Debug;netcoreapp3.1-Release
+ netcoreapp
+ netfx
+ Debug;Release;AnyCPU;x86;x64$(ObjFolder)$(Configuration).$(Platform)\$(AddOnName)$(BinFolder)$(Configuration).$(Platform)\$(AddOnName)
@@ -19,13 +19,13 @@
-
+
-
-
-
-
-
+
+
+
+
+
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs
index ef1758bf8e..2a7a4267b6 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/SqlColumnEncryptionAzureKeyVaultProvider.cs
@@ -3,52 +3,36 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Collections.Generic;
-using Microsoft.Data.SqlClient;
-using System.Diagnostics;
-using System.Globalization;
using System.Linq;
-using System.Security.Cryptography;
using System.Text;
-using System.Threading.Tasks;
-using Microsoft.Azure.KeyVault;
-using Microsoft.Azure.KeyVault.WebKey;
-using Microsoft.Azure.KeyVault.Models;
+using Azure.Core;
+using Azure.Security.KeyVault.Keys.Cryptography;
+using static Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider.Validator;
namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
{
///
/// Implementation of column master key store provider that allows client applications to access data when a
- /// column master key is stored in Microsoft Azure Key Vault. For more information on Always Encrypted, please refer to: https://aka.ms/AlwaysEncrypted.
+ /// column master key is stored in Microsoft Azure Key Vault.
+ ///
+ /// For more information on Always Encrypted, please refer to: https://aka.ms/AlwaysEncrypted.
///
/// A Column Encryption Key encrypted with certificate store provider should be decryptable by this provider and vice versa.
///
- /// Envelope Format for the encrypted column encryption key
- /// version + keyPathLength + ciphertextLength + keyPath + ciphertext + signature
+ /// Envelope Format for the encrypted column encryption key :
+ /// version + keyPathLength + ciphertextLength + keyPath + ciphertext + signature
///
- /// version: A single byte indicating the format version.
- /// keyPathLength: Length of the keyPath.
- /// ciphertextLength: ciphertext length
- /// keyPath: keyPath used to encrypt the column encryption key. This is only used for troubleshooting purposes and is not verified during decryption.
- /// ciphertext: Encrypted column encryption key
- /// signature: Signature of the entire byte array. Signature is validated before decrypting the column encryption key.
+ /// - version: A single byte indicating the format version.
+ /// - keyPathLength: Length of the keyPath.
+ /// - ciphertextLength: ciphertext length
+ /// - keyPath: keyPath used to encrypt the column encryption key. This is only used for troubleshooting purposes and is not verified during decryption.
+ /// - ciphertext: Encrypted column encryption key
+ /// - signature: Signature of the entire byte array. Signature is validated before decrypting the column encryption key.
///
///
/// API only once in the lifetime of driver to register this custom provider by implementing a custom Authentication Callback mechanism.
- ///
- /// Once the provider is registered, it can used to perform Always Encrypted operations by creating Column Master Key using Azure Key Vault Key Identifier URL.
- ///
- /// ## Example
- ///
- /// Sample C# applications to demonstrate Always Encrypted use with Azure Key Vault are available at links below:
- ///
- /// - [Example: Using Azure Key Vault with Always Encrypted](~/connect/ado-net/sql/azure-key-vault-example.md)
- /// - [Example: Using Azure Key Vault with Always Encrypted with enclaves enabled](~/connect/ado-net/sql/azure-key-vault-enclave-example.md)
+ /// For more information, see: [Using the Azure Key Vault Provider](/sql/connect/ado-net/sql/sqlclient-support-always-encrypted#using-the-azure-key-vault-provider)
/// ]]>
///
public class SqlColumnEncryptionAzureKeyVaultProvider : SqlColumnEncryptionKeyStoreProvider
@@ -61,18 +45,16 @@ public class SqlColumnEncryptionAzureKeyVaultProvider : SqlColumnEncryptionKeySt
public const string ProviderName = "AZURE_KEY_VAULT";
///
- /// Algorithm version
+ /// Key storage and cryptography client
///
- private readonly byte[] firstVersion = new byte[] { 0x01 };
+ private AzureSqlKeyCryptographer KeyCryptographer { get; set; }
///
- /// Azure Key Vault Client
+ /// Algorithm version
///
- public KeyVaultClient KeyVaultClient
- {
- get;
- private set;
- }
+ private readonly static byte[] s_firstVersion = new byte[] { 0x01 };
+
+ private readonly static KeyWrapAlgorithm s_keyWrapAlgorithm = KeyWrapAlgorithm.RsaOaep;
///
/// List of Trusted Endpoints
@@ -80,73 +62,93 @@ public KeyVaultClient KeyVaultClient
///
public readonly string[] TrustedEndPoints;
+ ///
+ /// A cache of column encryption keys (once they are decrypted). This is useful for rapidly decrypting multiple data values.
+ ///
+ private readonly LocalCache _columnEncryptionKeyCache = new() { TimeToLive = TimeSpan.FromHours(2) };
+
+ ///
+ /// A cache for storing the results of signature verification of column master key metadata.
+ ///
+ private readonly LocalCache, bool> _columnMasterKeyMetadataSignatureVerificationCache =
+ new(maxSizeLimit: 2000) { TimeToLive = TimeSpan.FromDays(10) };
+
+ ///
+ /// Gets or sets the lifespan of the decrypted column encryption key in the cache.
+ /// Once the timespan has elapsed, the decrypted column encryption key is discarded
+ /// and must be revalidated.
+ ///
+ ///
+ /// Internally, there is a cache of column encryption keys (once they are decrypted).
+ /// This is useful for rapidly decrypting multiple data values. The default value is 2 hours.
+ /// Setting the to zero disables caching.
+ ///
+ public override TimeSpan? ColumnEncryptionKeyCacheTtl
+ {
+ get => _columnEncryptionKeyCache.TimeToLive;
+ set => _columnEncryptionKeyCache.TimeToLive = value;
+ }
+
#endregion
+ #region Constructors
///
- /// Constructor that takes a callback function to authenticate to AAD. This is used by KeyVaultClient at runtime
- /// to authenticate to Azure Key Vault.
+ /// Constructor that takes an implementation of Token Credential that is capable of providing an OAuth Token.
///
- /// Callback function used for authenticating to AAD.
- public SqlColumnEncryptionAzureKeyVaultProvider(KeyVaultClient.AuthenticationCallback authenticationCallback) :
- this(authenticationCallback, Constants.AzureKeyVaultPublicDomainNames)
+ ///
+ public SqlColumnEncryptionAzureKeyVaultProvider(TokenCredential tokenCredential) :
+ this(tokenCredential, Constants.AzureKeyVaultPublicDomainNames)
{ }
///
- /// Constructor that takes a callback function to authenticate to AAD and a trusted endpoint.
+ /// Constructor that takes an implementation of Token Credential that is capable of providing an OAuth Token and a trusted endpoint.
///
- /// Callback function used for authenticating to AAD.
- /// TrustedEndpoint is used to validate the master key path
- public SqlColumnEncryptionAzureKeyVaultProvider(KeyVaultClient.AuthenticationCallback authenticationCallback, string trustedEndPoint) :
- this(authenticationCallback, new[] { trustedEndPoint })
+ /// Instance of an implementation of Token Credential that is capable of providing an OAuth Token.
+ /// TrustedEndpoint is used to validate the master key path.
+ public SqlColumnEncryptionAzureKeyVaultProvider(TokenCredential tokenCredential, string trustedEndPoint) :
+ this(tokenCredential, new[] { trustedEndPoint })
{ }
///
- /// Constructor that takes a callback function to authenticate to AAD and an array of trusted endpoints. The callback function
- /// is used by KeyVaultClient at runtime to authenticate to Azure Key Vault.
+ /// Constructor that takes an instance of an implementation of Token Credential that is capable of providing an OAuth Token
+ /// and an array of trusted endpoints.
///
- /// Callback function used for authenticating to AAD.
- /// TrustedEndpoints are used to validate the master key path
- public SqlColumnEncryptionAzureKeyVaultProvider(KeyVaultClient.AuthenticationCallback authenticationCallback, string[] trustedEndPoints)
+ /// Instance of an implementation of Token Credential that is capable of providing an OAuth Token
+ /// TrustedEndpoints are used to validate the master key path
+ public SqlColumnEncryptionAzureKeyVaultProvider(TokenCredential tokenCredential, string[] trustedEndpoints)
{
- if (authenticationCallback == null)
- {
- throw new ArgumentNullException("authenticationCallback");
- }
-
- if (trustedEndPoints == null || trustedEndPoints.Length == 0)
- {
- throw new ArgumentException(Strings.InvalidTrustedEndpointsList);
- }
-
- foreach (string trustedEndPoint in trustedEndPoints)
- {
- if (String.IsNullOrWhiteSpace(trustedEndPoint))
- {
- throw new ArgumentException(String.Format(Strings.InvalidTrustedEndpointTemplate, trustedEndPoint));
- }
- }
-
- KeyVaultClient = new KeyVaultClient(authenticationCallback);
- this.TrustedEndPoints = trustedEndPoints;
+ using var _ = AKVScope.Create();
+ ValidateNotNull(tokenCredential, nameof(tokenCredential));
+ ValidateNotNull(trustedEndpoints, nameof(trustedEndpoints));
+ ValidateNotEmpty(trustedEndpoints, nameof(trustedEndpoints));
+ ValidateNotNullOrWhitespaceForEach(trustedEndpoints, nameof(trustedEndpoints));
+
+ KeyCryptographer = new AzureSqlKeyCryptographer(tokenCredential);
+ TrustedEndPoints = trustedEndpoints;
}
+ #endregion
#region Public methods
///
- /// Uses an asymmetric key identified by the key path to sign the masterkey metadata consisting of (masterKeyPath, allowEnclaveComputations bit, providerName).
+ /// Uses an asymmetric key identified by the key path to sign the master key metadata consisting of (masterKeyPath, allowEnclaveComputations bit, providerName).
///
/// Complete path of an asymmetric key. Path format is specific to a key store provider.
- /// Boolean indicating whether this key can be sent to trusted enclave
+ /// Boolean indicating whether this key can be sent to a trusted enclave
/// Encrypted column encryption key
public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations)
{
- var hash = ComputeMasterKeyMetadataHash(masterKeyPath, allowEnclaveComputations, isSystemOp: false);
- byte[] signedHash = AzureKeyVaultSignHashedData(hash, masterKeyPath);
- return signedHash;
+ using var _ = AKVScope.Create();
+ ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: false);
+
+ // Also validates key is of RSA type.
+ KeyCryptographer.AddKey(masterKeyPath);
+ byte[] message = CompileMasterKeyMetadata(masterKeyPath, allowEnclaveComputations);
+ return KeyCryptographer.SignData(message, masterKeyPath);
}
///
- /// Uses an asymmetric key identified by the key path to verify the masterkey metadata consisting of (masterKeyPath, allowEnclaveComputations bit, providerName).
+ /// Uses an asymmetric key identified by the key path to verify the master key metadata consisting of (masterKeyPath, allowEnclaveComputations bit, providerName).
///
/// Complete path of an asymmetric key. Path format is specific to a key store provider.
/// Boolean indicating whether this key can be sent to trusted enclave
@@ -154,422 +156,252 @@ public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool al
/// Boolean indicating whether the master key metadata can be verified based on the provided signature
public override bool VerifyColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations, byte[] signature)
{
- var hash = ComputeMasterKeyMetadataHash(masterKeyPath, allowEnclaveComputations, isSystemOp: true);
- return AzureKeyVaultVerifySignature(hash, signature, masterKeyPath);
+ using var _ = AKVScope.Create();
+ ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
+
+ var key = Tuple.Create(masterKeyPath, allowEnclaveComputations, ToHexString(signature));
+ return GetOrCreateSignatureVerificationResult(key, VerifyColumnMasterKeyMetadata);
+
+ bool VerifyColumnMasterKeyMetadata()
+ {
+ // Also validates key is of RSA type.
+ KeyCryptographer.AddKey(masterKeyPath);
+ byte[] message = CompileMasterKeyMetadata(masterKeyPath, allowEnclaveComputations);
+ return KeyCryptographer.VerifyData(message, signature, masterKeyPath);
+ }
}
///
/// This function uses the asymmetric key specified by the key path
/// and decrypts an encrypted CEK with RSA encryption algorithm.
///
- /// Complete path of an asymmetric key in AKV
+ /// Complete path of an asymmetric key in Azure Key Vault
/// Asymmetric Key Encryption Algorithm
/// Encrypted Column Encryption Key
/// Plain text column encryption key
public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] encryptedColumnEncryptionKey)
{
+ using var _ = AKVScope.Create();
// Validate the input parameters
- this.ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
+ ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
+ ValidateEncryptionAlgorithm(encryptionAlgorithm, isSystemOp: true);
+ ValidateNotNull(encryptedColumnEncryptionKey, nameof(encryptedColumnEncryptionKey));
+ ValidateNotEmpty(encryptedColumnEncryptionKey, nameof(encryptedColumnEncryptionKey));
+ ValidateVersionByte(encryptedColumnEncryptionKey[0], s_firstVersion[0]);
- if (null == encryptedColumnEncryptionKey)
- {
- throw new ArgumentNullException(Constants.AeParamEncryptedCek, Strings.NullCekvInternal);
- }
+ return GetOrCreateColumnEncryptionKey(ToHexString(encryptedColumnEncryptionKey), DecryptEncryptionKey);
- if (0 == encryptedColumnEncryptionKey.Length)
+ byte[] DecryptEncryptionKey()
{
- throw new ArgumentException(Strings.EmptyCekvInternal, Constants.AeParamEncryptedCek);
- }
-
- // Validate encryptionAlgorithm
- this.ValidateEncryptionAlgorithm(ref encryptionAlgorithm, isSystemOp: true);
-
- // Validate whether the key is RSA one or not and then get the key size
- int keySizeInBytes = GetAKVKeySize(masterKeyPath);
+ // Also validates whether the key is RSA one or not and then get the key size
+ KeyCryptographer.AddKey(masterKeyPath);
- // Validate and decrypt the EncryptedColumnEncryptionKey
- // Format is
- // version + keyPathLength + ciphertextLength + keyPath + ciphertext + signature
- //
- // keyPath is present in the encrypted column encryption key for identifying the original source of the asymmetric key pair and
- // we will not validate it against the data contained in the CMK metadata (masterKeyPath).
+ int keySizeInBytes = KeyCryptographer.GetKeySize(masterKeyPath);
- // Validate the version byte
- if (encryptedColumnEncryptionKey[0] != firstVersion[0])
- {
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, Strings.InvalidAlgorithmVersionTemplate,
- encryptedColumnEncryptionKey[0].ToString(@"X2"),
- firstVersion[0].ToString("X2")),
- Constants.AeParamEncryptedCek);
- }
+ // Get key path length
+ int currentIndex = s_firstVersion.Length;
+ ushort keyPathLength = BitConverter.ToUInt16(encryptedColumnEncryptionKey, currentIndex);
+ currentIndex += sizeof(ushort);
- // Get key path length
- int currentIndex = firstVersion.Length;
- UInt16 keyPathLength = BitConverter.ToUInt16(encryptedColumnEncryptionKey, currentIndex);
- currentIndex += sizeof(UInt16);
+ // Get ciphertext length
+ ushort cipherTextLength = BitConverter.ToUInt16(encryptedColumnEncryptionKey, currentIndex);
+ currentIndex += sizeof(ushort);
- // Get ciphertext length
- UInt16 cipherTextLength = BitConverter.ToUInt16(encryptedColumnEncryptionKey, currentIndex);
- currentIndex += sizeof(UInt16);
+ // Skip KeyPath
+ // KeyPath exists only for troubleshooting purposes and doesnt need validation.
+ currentIndex += keyPathLength;
- // Skip KeyPath
- // KeyPath exists only for troubleshooting purposes and doesnt need validation.
- currentIndex += keyPathLength;
-
- // validate the ciphertext length
- if (cipherTextLength != keySizeInBytes)
- {
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, Strings.InvalidCiphertextLengthTemplate,
- cipherTextLength,
- keySizeInBytes,
- masterKeyPath),
- Constants.AeParamEncryptedCek);
- }
+ // validate the ciphertext length
+ if (cipherTextLength != keySizeInBytes)
+ {
+ AKVEventSource.Log.TryTraceEvent("Cipher Text length: {0}", cipherTextLength);
+ AKVEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
+ throw ADP.InvalidCipherTextLength(cipherTextLength, keySizeInBytes, masterKeyPath);
+ }
- // Validate the signature length
- int signatureLength = encryptedColumnEncryptionKey.Length - currentIndex - cipherTextLength;
- if (signatureLength != keySizeInBytes)
- {
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, Strings.InvalidSignatureLengthTemplate,
- signatureLength,
- keySizeInBytes,
- masterKeyPath),
- Constants.AeParamEncryptedCek);
- }
+ // Validate the signature length
+ int signatureLength = encryptedColumnEncryptionKey.Length - currentIndex - cipherTextLength;
+ if (signatureLength != keySizeInBytes)
+ {
+ AKVEventSource.Log.TryTraceEvent("Signature length: {0}", signatureLength);
+ AKVEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
+ throw ADP.InvalidSignatureLengthTemplate(signatureLength, keySizeInBytes, masterKeyPath);
+ }
- // Get ciphertext
- byte[] cipherText = new byte[cipherTextLength];
- Buffer.BlockCopy(encryptedColumnEncryptionKey, currentIndex, cipherText, 0, cipherTextLength);
- currentIndex += cipherTextLength;
+ // Get ciphertext
+ byte[] cipherText = encryptedColumnEncryptionKey.Skip(currentIndex).Take(cipherTextLength).ToArray();
+ currentIndex += cipherTextLength;
- // Get signature
- byte[] signature = new byte[signatureLength];
- Buffer.BlockCopy(encryptedColumnEncryptionKey, currentIndex, signature, 0, signature.Length);
+ // Get signature
+ byte[] signature = encryptedColumnEncryptionKey.Skip(currentIndex).Take(signatureLength).ToArray();
- // Compute the hash to validate the signature
- byte[] hash;
- using (SHA256 sha256 = SHA256.Create())
- {
- sha256.TransformFinalBlock(encryptedColumnEncryptionKey, 0, encryptedColumnEncryptionKey.Length - signature.Length);
- hash = sha256.Hash;
- }
+ // Compute the message to validate the signature
+ byte[] message = encryptedColumnEncryptionKey.Take(encryptedColumnEncryptionKey.Length - signatureLength).ToArray();
- if (null == hash)
- {
- throw new CryptographicException(Strings.NullHash);
- }
+ if (null == message)
+ {
+ throw ADP.NullHashFound();
+ }
- // Validate the signature
- if (!AzureKeyVaultVerifySignature(hash, signature, masterKeyPath))
- {
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, Strings.InvalidSignatureTemplate,
- masterKeyPath),
- Constants.AeParamEncryptedCek);
+ if (!KeyCryptographer.VerifyData(message, signature, masterKeyPath))
+ {
+ AKVEventSource.Log.TryTraceEvent("Signature could not be verified.");
+ throw ADP.InvalidSignatureTemplate(masterKeyPath);
+ }
+ return KeyCryptographer.UnwrapKey(s_keyWrapAlgorithm, cipherText, masterKeyPath);
}
-
- // Decrypt the CEK
- return this.AzureKeyVaultUnWrap(masterKeyPath, encryptionAlgorithm, cipherText);
}
///
/// This function uses the asymmetric key specified by the key path
/// and encrypts CEK with RSA encryption algorithm.
///
- /// Complete path of an asymmetric key in AKV
+ /// Complete path of an asymmetric key in Azure Key Vault
/// Asymmetric Key Encryption Algorithm
- /// Plain text column encryption key
+ /// The plaintext column encryption key.
/// Encrypted column encryption key
public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey)
{
+ using var _ = AKVScope.Create();
// Validate the input parameters
- this.ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
-
- if (null == columnEncryptionKey)
- {
- throw new ArgumentNullException(Constants.AeParamColumnEncryptionKey, Strings.NullCek);
- }
-
- if (0 == columnEncryptionKey.Length)
- {
- throw new ArgumentException(Strings.EmptyCek, Constants.AeParamColumnEncryptionKey);
- }
-
- // Validate encryptionAlgorithm
- this.ValidateEncryptionAlgorithm(ref encryptionAlgorithm, isSystemOp: false);
+ ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp: true);
+ ValidateEncryptionAlgorithm(encryptionAlgorithm, isSystemOp: true);
+ ValidateNotNull(columnEncryptionKey, nameof(columnEncryptionKey));
+ ValidateNotEmpty(columnEncryptionKey, nameof(columnEncryptionKey));
- // Validate whether the key is RSA one or not and then get the key size
- int keySizeInBytes = GetAKVKeySize(masterKeyPath);
+ // Also validates whether the key is RSA one or not and then get the key size
+ KeyCryptographer.AddKey(masterKeyPath);
+ int keySizeInBytes = KeyCryptographer.GetKeySize(masterKeyPath);
// Construct the encryptedColumnEncryptionKey
// Format is
- // version + keyPathLength + ciphertextLength + ciphertext + keyPath + signature
- //
- // We currently only support one version
- byte[] version = new byte[] { firstVersion[0] };
+ // s_firstVersion + keyPathLength + ciphertextLength + keyPath + ciphertext + signature
// Get the Unicode encoded bytes of cultureinvariant lower case masterKeyPath
byte[] masterKeyPathBytes = Encoding.Unicode.GetBytes(masterKeyPath.ToLowerInvariant());
- byte[] keyPathLength = BitConverter.GetBytes((Int16)masterKeyPathBytes.Length);
+ byte[] keyPathLength = BitConverter.GetBytes((short)masterKeyPathBytes.Length);
// Encrypt the plain text
- byte[] cipherText = this.AzureKeyVaultWrap(masterKeyPath, encryptionAlgorithm, columnEncryptionKey);
- byte[] cipherTextLength = BitConverter.GetBytes((Int16)cipherText.Length);
+ byte[] cipherText = KeyCryptographer.WrapKey(s_keyWrapAlgorithm, columnEncryptionKey, masterKeyPath);
+ byte[] cipherTextLength = BitConverter.GetBytes((short)cipherText.Length);
if (cipherText.Length != keySizeInBytes)
{
- throw new CryptographicException(Strings.CiphertextLengthMismatch);
+ AKVEventSource.Log.TryTraceEvent("Cipher Text length: {0}", cipherText.Length);
+ AKVEventSource.Log.TryTraceEvent("keySizeInBytes: {0}", keySizeInBytes);
+ throw ADP.CipherTextLengthMismatch();
}
- // Compute hash
+ // Compute message
// SHA-2-256(version + keyPathLength + ciphertextLength + keyPath + ciphertext)
- byte[] hash;
- using (SHA256 sha256 = SHA256.Create())
- {
- sha256.TransformBlock(version, 0, version.Length, version, 0);
- sha256.TransformBlock(keyPathLength, 0, keyPathLength.Length, keyPathLength, 0);
- sha256.TransformBlock(cipherTextLength, 0, cipherTextLength.Length, cipherTextLength, 0);
- sha256.TransformBlock(masterKeyPathBytes, 0, masterKeyPathBytes.Length, masterKeyPathBytes, 0);
- sha256.TransformFinalBlock(cipherText, 0, cipherText.Length);
- hash = sha256.Hash;
- }
+ byte[] message = s_firstVersion.Concat(keyPathLength).Concat(cipherTextLength).Concat(masterKeyPathBytes).Concat(cipherText).ToArray();
- // Sign the hash
- byte[] signedHash = AzureKeyVaultSignHashedData(hash, masterKeyPath);
+ // Sign the message
+ byte[] signature = KeyCryptographer.SignData(message, masterKeyPath);
- if (signedHash.Length != keySizeInBytes)
+ if (signature.Length != keySizeInBytes)
{
- throw new CryptographicException(Strings.HashLengthMismatch);
+ throw ADP.HashLengthMismatch();
}
- if (!this.AzureKeyVaultVerifySignature(hash, signedHash, masterKeyPath))
- {
- throw new CryptographicException(Strings.InvalidSignature);
- }
-
- // Construct the encrypted column encryption key
- // EncryptedColumnEncryptionKey = version + keyPathLength + ciphertextLength + keyPath + ciphertext + signature
- int encryptedColumnEncryptionKeyLength = version.Length + cipherTextLength.Length + keyPathLength.Length + cipherText.Length + masterKeyPathBytes.Length + signedHash.Length;
- byte[] encryptedColumnEncryptionKey = new byte[encryptedColumnEncryptionKeyLength];
-
- // Copy version byte
- int currentIndex = 0;
- Buffer.BlockCopy(version, 0, encryptedColumnEncryptionKey, currentIndex, version.Length);
- currentIndex += version.Length;
-
- // Copy key path length
- Buffer.BlockCopy(keyPathLength, 0, encryptedColumnEncryptionKey, currentIndex, keyPathLength.Length);
- currentIndex += keyPathLength.Length;
+ ValidateSignature(masterKeyPath, message, signature);
- // Copy ciphertext length
- Buffer.BlockCopy(cipherTextLength, 0, encryptedColumnEncryptionKey, currentIndex, cipherTextLength.Length);
- currentIndex += cipherTextLength.Length;
-
- // Copy key path
- Buffer.BlockCopy(masterKeyPathBytes, 0, encryptedColumnEncryptionKey, currentIndex, masterKeyPathBytes.Length);
- currentIndex += masterKeyPathBytes.Length;
-
- // Copy ciphertext
- Buffer.BlockCopy(cipherText, 0, encryptedColumnEncryptionKey, currentIndex, cipherText.Length);
- currentIndex += cipherText.Length;
-
- // copy the signature
- Buffer.BlockCopy(signedHash, 0, encryptedColumnEncryptionKey, currentIndex, signedHash.Length);
-
- return encryptedColumnEncryptionKey;
+ return message.Concat(signature).ToArray();
}
#endregion
#region Private methods
- ///
- /// This function validates that the encryption algorithm is RSA_OAEP and if it is not,
- /// then throws an exception
- ///
- /// Asymmetric key encryption algorithm
- /// is the operation a system operation
- private void ValidateEncryptionAlgorithm(ref string encryptionAlgorithm, bool isSystemOp)
- {
- // This validates that the encryption algorithm is RSA_OAEP
- if (null == encryptionAlgorithm)
- {
- if (isSystemOp)
- {
- throw new ArgumentNullException(Constants.AeParamEncryptionAlgorithm, Strings.NullAlgorithmInternal);
- }
- else
- {
- throw new ArgumentNullException(Constants.AeParamEncryptionAlgorithm, Strings.NullAlgorithm);
- }
- }
-
- // Transform to standard format (dash instead of underscore) to support both "RSA_OAEP" and "RSA-OAEP"
- if (encryptionAlgorithm.Equals("RSA_OAEP", StringComparison.OrdinalIgnoreCase))
- {
- encryptionAlgorithm = JsonWebKeyEncryptionAlgorithm.RSAOAEP;
- }
-
- if (String.Equals(encryptionAlgorithm, JsonWebKeyEncryptionAlgorithm.RSAOAEP, StringComparison.OrdinalIgnoreCase) != true)
- {
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, Strings.InvalidKeyAlgorithm,
- encryptionAlgorithm, "RSA_OAEP' or 'RSA-OAEP"), // For supporting both algorithm formats.
- Constants.AeParamEncryptionAlgorithm);
- }
- }
-
- private byte[] ComputeMasterKeyMetadataHash(string masterKeyPath, bool allowEnclaveComputations, bool isSystemOp)
- {
- // Validate the input parameters
- ValidateNonEmptyAKVPath(masterKeyPath, isSystemOp);
-
- // Validate whether the key is RSA one or not and then get the key size
- GetAKVKeySize(masterKeyPath);
-
- string masterkeyMetadata = ProviderName + masterKeyPath + allowEnclaveComputations;
- byte[] masterkeyMetadataBytes = Encoding.Unicode.GetBytes(masterkeyMetadata.ToLowerInvariant());
-
- // Compute hash
- byte[] hash;
- using (SHA256 sha256 = SHA256.Create())
- {
- sha256.TransformFinalBlock(masterkeyMetadataBytes, 0, masterkeyMetadataBytes.Length);
- hash = sha256.Hash;
- }
- return hash;
- }
-
///
/// Checks if the Azure Key Vault key path is Empty or Null (and raises exception if they are).
///
internal void ValidateNonEmptyAKVPath(string masterKeyPath, bool isSystemOp)
{
// throw appropriate error if masterKeyPath is null or empty
- if (String.IsNullOrWhiteSpace(masterKeyPath))
+ if (string.IsNullOrWhiteSpace(masterKeyPath))
{
- string errorMessage = null == masterKeyPath
- ? Strings.NullAkvPath
- : String.Format(CultureInfo.InvariantCulture, Strings.InvalidAkvPathTemplate, masterKeyPath);
-
- if (isSystemOp)
- {
- throw new ArgumentNullException(Constants.AeParamMasterKeyPath, errorMessage);
- }
-
- throw new ArgumentException(errorMessage, Constants.AeParamMasterKeyPath);
+ AKVEventSource.Log.TryTraceEvent("Azure Key Vault URI found null or empty.");
+ throw ADP.InvalidAKVPath(masterKeyPath, isSystemOp);
}
- Uri parsedUri;
-
- if (!Uri.TryCreate(masterKeyPath, UriKind.Absolute, out parsedUri))
+ if (!Uri.TryCreate(masterKeyPath, UriKind.Absolute, out Uri parsedUri) || parsedUri.Segments.Length < 3)
{
// Return an error indicating that the AKV url is invalid.
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, Strings.InvalidAkvUrlTemplate, masterKeyPath), Constants.AeParamMasterKeyPath);
+ AKVEventSource.Log.TryTraceEvent("URI could not be created with provided master key path: {0}", masterKeyPath);
+ throw ADP.InvalidAKVUrl(masterKeyPath);
}
// A valid URI.
// Check if it is pointing to trusted endpoint.
- foreach (string trustedEndPoint in this.TrustedEndPoints)
+ foreach (string trustedEndPoint in TrustedEndPoints)
{
if (parsedUri.Host.EndsWith(trustedEndPoint, StringComparison.OrdinalIgnoreCase))
{
+ AKVEventSource.Log.TryTraceEvent("Azure Key Vault URI validated successfully.");
return;
}
}
// Return an error indicating that the AKV url is invalid.
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, Strings.InvalidAkvKeyPathTrustedTemplate, masterKeyPath, String.Join(", ", this.TrustedEndPoints.ToArray())), Constants.AeParamMasterKeyPath);
+ AKVEventSource.Log.TryTraceEvent("Master Key Path could not be validated as it does not end with trusted endpoints: {0}", masterKeyPath);
+ throw ADP.InvalidAKVUrlTrustedEndpoints(masterKeyPath, string.Join(", ", TrustedEndPoints.ToArray()));
}
- ///
- /// Encrypt the text using specified Azure Key Vault key.
- ///
- /// Azure Key Vault key url.
- /// Encryption Algorithm.
- /// Plain text Column Encryption Key.
- /// Returns an encrypted blob or throws an exception if there are any errors.
- private byte[] AzureKeyVaultWrap(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey)
+ private void ValidateSignature(string masterKeyPath, byte[] message, byte[] signature)
{
- if (null == columnEncryptionKey)
+ if (!KeyCryptographer.VerifyData(message, signature, masterKeyPath))
{
- throw new ArgumentNullException("columnEncryptionKey");
+ AKVEventSource.Log.TryTraceEvent("Signature could not be verified.");
+ throw ADP.InvalidSignature();
}
-
- var wrappedKey = Task.Run(() => KeyVaultClient.WrapKeyAsync(masterKeyPath, encryptionAlgorithm, columnEncryptionKey)).Result;
- return wrappedKey.Result;
+ AKVEventSource.Log.TryTraceEvent("Signature verified successfully.");
}
- ///
- /// Encrypt the text using specified Azure Key Vault key.
- ///
- /// Azure Key Vault key url.
- /// Encryption Algorithm.
- /// Encrypted Column Encryption Key.
- /// Returns the decrypted plaintext Column Encryption Key or throws an exception if there are any errors.
- private byte[] AzureKeyVaultUnWrap(string masterKeyPath, string encryptionAlgorithm, byte[] encryptedColumnEncryptionKey)
+ private byte[] CompileMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations)
{
- if (null == encryptedColumnEncryptionKey)
- {
- throw new ArgumentNullException("encryptedColumnEncryptionKey");
- }
-
- if (0 == encryptedColumnEncryptionKey.Length)
- {
- throw new ArgumentException(Strings.EncryptedCekEmpty);
- }
-
-
- var unwrappedKey = Task.Run(() => KeyVaultClient.UnwrapKeyAsync(masterKeyPath, encryptionAlgorithm, encryptedColumnEncryptionKey)).Result;
-
- return unwrappedKey.Result;
+ string masterkeyMetadata = ProviderName + masterKeyPath + allowEnclaveComputations;
+ return Encoding.Unicode.GetBytes(masterkeyMetadata.ToLowerInvariant());
}
///
- /// Generates signature based on RSA PKCS#v1.5 scheme using a specified Azure Key Vault Key URL.
+ /// Converts the numeric value of each element of a specified array of bytes to its equivalent hexadecimal string representation.
///
- /// Text to sign.
- /// Azure Key Vault key url.
- /// Signature
- private byte[] AzureKeyVaultSignHashedData(byte[] dataToSign, string masterKeyPath)
+ /// An array of bytes to convert.
+ /// A string of hexadecimal characters
+ ///
+ /// Produces a string of hexadecimal character pairs preceded with "0x", where each pair represents the corresponding element in value; for example, "0x7F2C4A00".
+ ///
+ private string ToHexString(byte[] source)
{
- Debug.Assert((dataToSign != null) && (dataToSign.Length != 0));
-
- var signedData = Task.Run(() => KeyVaultClient.SignAsync(masterKeyPath, Constants.HashingAlgorithm, dataToSign)).Result;
+ if (source is null)
+ {
+ return null;
+ }
- return signedData.Result;
+ return "0x" + BitConverter.ToString(source).Replace("-", "");
}
///
- /// Verifies the given RSA PKCSv1.5 signature.
+ /// Returns the cached decrypted column encryption key, or unwraps the encrypted column encryption key if not present.
///
- ///
- ///
- /// Azure Key Vault key url.
- /// true if signature is valid, false if it is not valid
- private bool AzureKeyVaultVerifySignature(byte[] dataToVerify, byte[] signature, string masterKeyPath)
- {
- Debug.Assert((dataToVerify != null) && (dataToVerify.Length != 0));
- Debug.Assert((signature != null) && (signature.Length != 0));
-
- return Task.Run(() => KeyVaultClient.VerifyAsync(masterKeyPath, Constants.HashingAlgorithm, dataToVerify, signature)).Result;
- }
+ /// Encrypted Column Encryption Key
+ /// The delegate function that will decrypt the encrypted column encryption key.
+ /// The decrypted column encryption key.
+ ///
+ ///
+ ///
+ private byte[] GetOrCreateColumnEncryptionKey(string encryptedColumnEncryptionKey, Func createItem)
+ => _columnEncryptionKeyCache.GetOrCreate(encryptedColumnEncryptionKey, createItem);
///
- /// Gets the public Key size in bytes
+ /// Returns the cached signature verification result, or proceeds to verify if not present.
///
- /// Azure Key Vault Key path
- /// Key size in bytes
- private int GetAKVKeySize(string masterKeyPath)
- {
- KeyBundle retrievedKey = Task.Run(() => KeyVaultClient.GetKeyAsync(masterKeyPath)).Result;
-
- if (!String.Equals(retrievedKey.Key.Kty, JsonWebKeyType.Rsa, StringComparison.InvariantCultureIgnoreCase) &&
- !String.Equals(retrievedKey.Key.Kty, JsonWebKeyType.RsaHsm, StringComparison.InvariantCultureIgnoreCase))
- {
- throw new Exception(String.Format(CultureInfo.InvariantCulture, Strings.NonRsaKeyTemplate, retrievedKey.Key.Kty));
- }
-
- return retrievedKey.Key.N.Length;
- }
+ /// The encryptionKeyId, allowEnclaveComputations and hexadecimal signature.
+ /// The delegate function that will perform the verification.
+ ///
+ private bool GetOrCreateSignatureVerificationResult(Tuple keyInformation, Func createItem)
+ => _columnMasterKeyMetadataSignatureVerificationCache.GetOrCreate(keyInformation, createItem);
#endregion
}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.Designer.cs
index a725197027..fc5d88930a 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.Designer.cs
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.Designer.cs
@@ -10,8 +10,6 @@
namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
{
- using System;
-
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -71,55 +69,22 @@ internal Strings()
///
/// Looks up a localized string similar to CipherText length does not match the RSA key size..
///
- internal static string CiphertextLengthMismatch
+ internal static string CipherTextLengthMismatch
{
get
{
- return ResourceManager.GetString("CiphertextLengthMismatch", resourceCulture);
+ return ResourceManager.GetString("CipherTextLengthMismatch", resourceCulture);
}
}
///
- /// Looks up a localized string similar to Empty column encryption key specified..
+ /// Looks up a localized string similar to Internal error. Empty '{0}' specified..
///
- internal static string EmptyCek
+ internal static string EmptyArgumentInternal
{
get
{
- return ResourceManager.GetString("EmptyCek", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Empty encrypted column encryption key specified..
- ///
- internal static string EmptyCekv
- {
- get
- {
- return ResourceManager.GetString("EmptyCekv", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Internal error: Empty encrypted column encryption key specified..
- ///
- internal static string EmptyCekvInternal
- {
- get
- {
- return ResourceManager.GetString("EmptyCekvInternal", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to encryptedColumnEncryptionKey length should not be zero..
- ///
- internal static string EncryptedCekEmpty
- {
- get
- {
- return ResourceManager.GetString("EncryptedCekEmpty", resourceCulture);
+ return ResourceManager.GetString("EmptyArgumentInternal", resourceCulture);
}
}
@@ -233,25 +198,14 @@ internal static string InvalidSignatureTemplate
}
}
- ///
- /// Looks up a localized string similar to trustedEndPoints cannot be null or empty..
- ///
- internal static string InvalidTrustedEndpointsList
- {
- get
- {
- return ResourceManager.GetString("InvalidTrustedEndpointsList", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Invalid trusted endpoint specified: '{0}'; a trusted endpoint must have a value..
///
- internal static string InvalidTrustedEndpointTemplate
+ internal static string NullOrWhitespaceForEach
{
get
{
- return ResourceManager.GetString("InvalidTrustedEndpointTemplate", resourceCulture);
+ return ResourceManager.GetString("NullOrWhitespaceForEach", resourceCulture);
}
}
@@ -299,39 +253,6 @@ internal static string NullAlgorithmInternal
}
}
- ///
- /// Looks up a localized string similar to Column encryption key cannot be null..
- ///
- internal static string NullCek
- {
- get
- {
- return ResourceManager.GetString("NullCek", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Encrypted column encryption key cannot be null..
- ///
- internal static string NullCekv
- {
- get
- {
- return ResourceManager.GetString("NullCekv", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Internal error: Encrypted column encryption key cannot be null..
- ///
- internal static string NullCekvInternal
- {
- get
- {
- return ResourceManager.GetString("NullCekvInternal", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to Hash should not be null while decrypting encrypted column encryption key..
///
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.resx b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.resx
index 7d4e2e6db3..039d1079d5 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.resx
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Strings.resx
@@ -117,23 +117,17 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- trustedEndPoints cannot be null or empty.
+
+ One or more of the elements in {0} are null or empty or consist of only whitespace.
-
- Invalid trusted endpoint specified: '{0}'; a trusted endpoint must have a value.
-
-
+
CipherText length does not match the RSA key size.
-
- Empty column encryption key specified.
-
-
- Empty encrypted column encryption key specified.
+
+ Internal error. Empty {0} specified.
-
- encryptedColumnEncryptionKey length should not be zero.
+
+ The key with identifier '{0}' was not found.Signed hash length does not match the RSA key size.
@@ -174,22 +168,10 @@
Key encryption algorithm cannot be null.
-
- Column encryption key cannot be null.
-
-
- Encrypted column encryption key cannot be null.
-
-
- Hash should not be null while decrypting encrypted column encryption key.
-
-
- Internal error. Empty encrypted column encryption key specified.
-
Internal error. Key encryption algorithm cannot be null.
-
- Internal error. Encrypted column encryption key cannot be null.
+
+ Hash should not be null while decrypting encrypted column encryption key.
diff --git a/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Utils.cs b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Utils.cs
new file mode 100644
index 0000000000..a5d74ed0a7
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/Utils.cs
@@ -0,0 +1,139 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Security.Cryptography;
+
+namespace Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider
+{
+ internal static class Validator
+ {
+ internal static void ValidateNotNull(object parameter, string name)
+ {
+ if (null == parameter)
+ {
+ throw ADP.NullArgument(name);
+ }
+ }
+
+ internal static void ValidateNotEmpty(IList parameter, string name)
+ {
+ if (parameter.Count == 0)
+ {
+ throw ADP.EmptyArgument(name);
+ }
+ }
+
+ internal static void ValidateNotNullOrWhitespaceForEach(string[] parameters, string name)
+ {
+ if (parameters.Any(s => string.IsNullOrWhiteSpace(s)))
+ {
+ throw ADP.NullOrWhitespaceForEach(name);
+ }
+ }
+
+ internal static void ValidateEncryptionAlgorithm(string encryptionAlgorithm, bool isSystemOp)
+ {
+ // This validates that the encryption algorithm is RSA_OAEP
+ if (null == encryptionAlgorithm)
+ {
+ throw ADP.NullAlgorithm(isSystemOp);
+ }
+
+ if (!encryptionAlgorithm.Equals("RSA_OAEP", StringComparison.OrdinalIgnoreCase)
+ && !encryptionAlgorithm.Equals("RSA-OAEP", StringComparison.OrdinalIgnoreCase))
+ {
+ throw ADP.InvalidKeyAlgorithm(encryptionAlgorithm);
+ }
+ }
+
+ internal static void ValidateVersionByte(byte encryptedByte, byte firstVersionByte)
+ {
+ // Validate and decrypt the EncryptedColumnEncryptionKey
+ // Format is
+ // version + keyPathLength + ciphertextLength + keyPath + ciphertext + signature
+ //
+ // keyPath is present in the encrypted column encryption key for identifying the original source of the asymmetric key pair and
+ // we will not validate it against the data contained in the CMK metadata (masterKeyPath).
+
+ // Validate the version byte
+ if (encryptedByte != firstVersionByte)
+ {
+ throw ADP.InvalidAlgorithmVersion(encryptedByte.ToString(@"X2"), firstVersionByte.ToString("X2"));
+ }
+ }
+ }
+
+ internal static class ADP
+ {
+ internal static ArgumentNullException NullArgument(string name) =>
+ new(name);
+
+ internal static ArgumentException EmptyArgument(string name) =>
+ new(string.Format(Strings.EmptyArgumentInternal, name));
+
+ internal static ArgumentException NullOrWhitespaceForEach(string name) =>
+ new(string.Format(Strings.NullOrWhitespaceForEach, name));
+
+ internal static KeyNotFoundException MasterKeyNotFound(string masterKeyPath) =>
+ new(string.Format(CultureInfo.InvariantCulture, Strings.InvalidSignatureTemplate, masterKeyPath));
+
+ internal static FormatException NonRsaKeyFormat(string keyType) =>
+ new(string.Format(CultureInfo.InvariantCulture, Strings.NonRsaKeyTemplate, keyType));
+
+ internal static ArgumentException InvalidCipherTextLength(ushort cipherTextLength, int keySizeInBytes, string masterKeyPath) =>
+ new(string.Format(CultureInfo.InvariantCulture, Strings.InvalidCiphertextLengthTemplate,
+ cipherTextLength, keySizeInBytes, masterKeyPath), Constants.AeParamEncryptedCek);
+
+ internal static ArgumentNullException NullAlgorithm(bool isSystemOp) =>
+ new(Constants.AeParamEncryptionAlgorithm, (isSystemOp ? Strings.NullAlgorithmInternal : Strings.NullAlgorithm));
+
+ internal static ArgumentException InvalidKeyAlgorithm(string encryptionAlgorithm) =>
+ new(string.Format(CultureInfo.InvariantCulture, Strings.InvalidKeyAlgorithm, encryptionAlgorithm,
+ "RSA_OAEP' or 'RSA-OAEP")/* For supporting both algorithm formats.*/, Constants.AeParamEncryptionAlgorithm);
+
+ internal static ArgumentException InvalidSignatureLengthTemplate(int signatureLength, int keySizeInBytes, string masterKeyPath) =>
+ new(string.Format(CultureInfo.InvariantCulture, Strings.InvalidSignatureLengthTemplate,
+ signatureLength, keySizeInBytes, masterKeyPath), Constants.AeParamEncryptedCek);
+
+ internal static Exception InvalidAlgorithmVersion(string encryptedBytes, string firstVersionBytes) =>
+ new ArgumentException(string.Format(CultureInfo.InvariantCulture, Strings.InvalidAlgorithmVersionTemplate,
+ encryptedBytes, firstVersionBytes), Constants.AeParamEncryptedCek);
+
+ internal static ArgumentException InvalidSignatureTemplate(string masterKeyPath) =>
+ new ArgumentException(string.Format(CultureInfo.InvariantCulture, Strings.InvalidSignatureTemplate, masterKeyPath),
+ Constants.AeParamEncryptedCek);
+
+ internal static CryptographicException InvalidSignature() => new(Strings.InvalidSignature);
+
+ internal static CryptographicException NullHashFound() => new(Strings.NullHash);
+
+ internal static CryptographicException CipherTextLengthMismatch() => new(Strings.CipherTextLengthMismatch);
+
+ internal static CryptographicException HashLengthMismatch() => new(Strings.HashLengthMismatch);
+
+ internal static ArgumentException InvalidAKVPath(string masterKeyPath, bool isSystemOp)
+ {
+ string errorMessage = null == masterKeyPath ? Strings.NullAkvPath
+ : string.Format(CultureInfo.InvariantCulture, Strings.InvalidAkvPathTemplate, masterKeyPath);
+ if (isSystemOp)
+ {
+ return new ArgumentNullException(Constants.AeParamMasterKeyPath, errorMessage);
+ }
+
+ return new ArgumentException(errorMessage, Constants.AeParamMasterKeyPath);
+ }
+
+ internal static ArgumentException InvalidAKVUrl(string masterKeyPath) =>
+ new(string.Format(CultureInfo.InvariantCulture, Strings.InvalidAkvUrlTemplate, masterKeyPath), Constants.AeParamMasterKeyPath);
+
+ internal static Exception InvalidAKVUrlTrustedEndpoints(string masterKeyPath, string endpoints) =>
+ new ArgumentException(string.Format(CultureInfo.InvariantCulture, Strings.InvalidAkvKeyPathTrustedTemplate, masterKeyPath, endpoints),
+ Constants.AeParamMasterKeyPath);
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props
index a76d932f17..762c5f9ed8 100644
--- a/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props
+++ b/src/Microsoft.Data.SqlClient/add-ons/Directory.Build.props
@@ -5,38 +5,39 @@
+ $(OS)
+ true
+ trueProject$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
- truetrue
+ $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
-
+
+
- $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))
+ net462
+ netstandard2.0
+ net6.0
+
-
-
-
- netcoreapp2.1
-
-
-
-
-
- netcoreapp2.1
- netcoreapp3.1
- net46
+
+
+ $(TargetNetFxVersion);$(TargetNetCoreVersion);$(TargetNetStandardVersion)
+ $(TargetNetCoreVersion);$(TargetNetStandardVersion)
-
+
- $(Configuration.Split('-')[0])
+ netstandard2.0;netstandard2.1
+ net6.0
+ net462
diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetCoreApp.cs
deleted file mode 100644
index 2b5db7d447..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.NetCoreApp.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-// ------------------------------------------------------------------------------
-// Changes to this file must follow the http://aka.ms/api-review process.
-// ------------------------------------------------------------------------------
-
-namespace Microsoft.Data.SqlClient
-{
- public partial class SqlDataReader : System.Data.Common.IDbColumnSchemaGenerator
- {
- ///
- public System.Collections.ObjectModel.ReadOnlyCollection GetColumnSchema() { throw null; }
- }
-
- ///
- public enum PoolBlockingPeriod
- {
- ///
- Auto = 0,
- ///
- AlwaysBlock = 1,
- ///
- NeverBlock = 2,
- }
-
- ///
- public sealed partial class SqlConnectionStringBuilder : System.Data.Common.DbConnectionStringBuilder
- {
- ///
- [System.ComponentModel.DisplayNameAttribute("Pool Blocking Period")]
- [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
- public PoolBlockingPeriod PoolBlockingPeriod { get { throw null; } set { } }
- }
-}
-
-namespace Microsoft.Data.SqlTypes
-{
- ///
- public sealed partial class SqlFileStream : System.IO.Stream
- {
- ///
- public SqlFileStream(string path, byte[] transactionContext, System.IO.FileAccess access) { }
- ///
- public SqlFileStream(string path, byte[] transactionContext, System.IO.FileAccess access, System.IO.FileOptions options, System.Int64 allocationSize) { }
- ///
- public string Name { get { throw null; } }
- ///
- public byte[] TransactionContext { get { throw null; } }
- ///
- public override bool CanRead { get { throw null; } }
- ///
- public override bool CanSeek { get { throw null; } }
- ///
- public override bool CanTimeout { get { throw null; } }
- ///
- public override bool CanWrite { get { throw null; } }
- ///
- public override long Length { get { throw null; } }
- ///
- public override long Position { get { throw null; } set { throw null; } }
- ///
- public override int ReadTimeout { get { throw null; } }
- ///
- public override int WriteTimeout { get { throw null; } }
- ///
- public override void Flush() { }
- ///
- public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
- ///
- public override int EndRead(System.IAsyncResult asyncResult) { throw null; }
- ///
- public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback callback, System.Object state) { throw null; }
- ///
- public override void EndWrite(System.IAsyncResult asyncResult) { }
- ///
- public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; }
- ///
- public override void SetLength(long value) { throw null; }
- ///
- public override int Read(byte[] buffer, int offset, int count) { throw null; }
- ///
- public override int ReadByte() { throw null; }
- ///
- public override void Write(byte[] buffer, int offset, int count) { throw null; }
- ///
- public override void WriteByte(byte value) { }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs
index 3cf24e9810..58dfd74e1e 100644
--- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+// NOTE: The current Microsoft.VSDesigner editor attributes are implemented for System.Data.SqlClient, and are not publicly available.
+// New attributes that are designed to work with Microsoft.Data.SqlClient and are publicly documented should be included in future.
[assembly: System.CLSCompliant(true)]
namespace Microsoft.Data
{
@@ -27,6 +29,68 @@ public SqlNotificationRequest(string userData, string options, int timeout) { }
///
public string UserData { get { throw null; } set { } }
}
+
+ ///
+ public sealed class SqlDataSourceEnumerator : System.Data.Common.DbDataSourceEnumerator
+ {
+ ///
+ public static SqlDataSourceEnumerator Instance { get; }
+ ///
+ public override System.Data.DataTable GetDataSources() { throw null; }
+ }
+}
+namespace Microsoft.Data.SqlTypes
+{
+ ///
+ public sealed partial class SqlFileStream : System.IO.Stream
+ {
+ ///
+ public SqlFileStream(string path, byte[] transactionContext, System.IO.FileAccess access) { }
+ ///
+ public SqlFileStream(string path, byte[] transactionContext, System.IO.FileAccess access, System.IO.FileOptions options, System.Int64 allocationSize) { }
+ ///
+ public string Name { get { throw null; } }
+ ///
+ public byte[] TransactionContext { get { throw null; } }
+ ///
+ public override bool CanRead { get { throw null; } }
+ ///
+ public override bool CanSeek { get { throw null; } }
+ ///
+ public override bool CanTimeout { get { throw null; } }
+ ///
+ public override bool CanWrite { get { throw null; } }
+ ///
+ public override long Length { get { throw null; } }
+ ///
+ public override long Position { get { throw null; } set { throw null; } }
+ ///
+ public override int ReadTimeout { get { throw null; } }
+ ///
+ public override int WriteTimeout { get { throw null; } }
+ ///
+ public override void Flush() { }
+ ///
+ public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
+ ///
+ public override int EndRead(System.IAsyncResult asyncResult) { throw null; }
+ ///
+ public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback callback, System.Object state) { throw null; }
+ ///
+ public override void EndWrite(System.IAsyncResult asyncResult) { }
+ ///
+ public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; }
+ ///
+ public override void SetLength(long value) { throw null; }
+ ///
+ public override int Read(byte[] buffer, int offset, int count) { throw null; }
+ ///
+ public override int ReadByte() { throw null; }
+ ///
+ public override void Write(byte[] buffer, int offset, int count) { throw null; }
+ ///
+ public override void WriteByte(byte value) { }
+ }
}
namespace Microsoft.Data.SqlClient
{
@@ -62,6 +126,16 @@ public enum ApplicationIntent
///
ReadWrite = 0
}
+ ///
+ public enum PoolBlockingPeriod
+ {
+ ///
+ Auto = 0,
+ ///
+ AlwaysBlock = 1,
+ ///
+ NeverBlock = 2,
+ }
///
public delegate void OnChangeEventHandler(object sender, Microsoft.Data.SqlClient.SqlNotificationEventArgs e);
///
@@ -99,16 +173,18 @@ public enum SqlAuthenticationMethod
ActiveDirectoryManagedIdentity = 7,
///
ActiveDirectoryMSI = 8,
+ ///
+ ActiveDirectoryDefault = 9,
///
NotSpecified = 0,
///
SqlPassword = 1
}
///
- public partial class SqlAuthenticationParameters
+ public class SqlAuthenticationParameters
{
///
- protected SqlAuthenticationParameters(Microsoft.Data.SqlClient.SqlAuthenticationMethod authenticationMethod, string serverName, string databaseName, string resource, string authority, string userId, string password, System.Guid connectionId) { }
+ protected SqlAuthenticationParameters(Microsoft.Data.SqlClient.SqlAuthenticationMethod authenticationMethod, string serverName, string databaseName, string resource, string authority, string userId, string password, System.Guid connectionId, int connectionTimeout) { }
///
public Microsoft.Data.SqlClient.SqlAuthenticationMethod AuthenticationMethod { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
///
@@ -125,6 +201,8 @@ protected SqlAuthenticationParameters(Microsoft.Data.SqlClient.SqlAuthentication
public string ServerName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
///
public string UserId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+ ///
+ public int ConnectionTimeout { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
}
///
public abstract partial class SqlAuthenticationProvider
@@ -305,6 +383,7 @@ public void Remove(SqlBulkCopyColumnOrderHint columnOrderHint) { }
///
public new void RemoveAt(int index) { }
}
+
///
[System.FlagsAttribute]
public enum SqlBulkCopyOptions
@@ -345,6 +424,22 @@ internal SqlClientFactory() { }
///
public override System.Data.Common.DbParameter CreateParameter() { throw null; }
}
+ ///
+ public partial class SqlClientLogger
+ {
+ ///
+ public SqlClientLogger() { }
+ ///
+ public bool IsLoggingEnabled { get { throw null; } }
+ ///
+ public void LogWarning(string type, string method, string message) { }
+ ///
+ public bool LogAssert(bool value, string type, string method, string message) { throw null; }
+ ///
+ public void LogError(string type, string method, string message) { }
+ ///
+ public void LogInfo(string type, string method, string message) { }
+ }
///
public static partial class SqlClientMetaDataCollectionNames
{
@@ -376,8 +471,10 @@ public static partial class SqlClientMetaDataCollectionNames
public static readonly string AllColumns;
///
public static readonly string ColumnSetColumns;
+ ///
+ public static readonly string StructuredTypeMembers;
}
-#if NETCOREAPP || NETSTANDARD21_AND_ABOVE
+#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
///
public enum SqlConnectionAttestationProtocol
{
@@ -387,15 +484,56 @@ public enum SqlConnectionAttestationProtocol
///
AAS = 1,
-#if ENCLAVE_SIMULATOR
- ///
- SIM = 2,
-#endif
+ ///
+ None = 2,
///
HGS = 3
}
#endif
+ ///
+ public enum SqlConnectionIPAddressPreference
+ {
+ ///
+ IPv4First = 0, // default
+
+ ///
+ IPv6First = 1,
+
+ ///
+ UsePlatformDefault = 2
+ }
+ ///
+ public sealed class SqlConnectionEncryptOption
+ {
+ ///
+ public static SqlConnectionEncryptOption Parse(string value) => throw null;
+ ///
+ public static bool TryParse(string value, out SqlConnectionEncryptOption result) => throw null;
+ ///
+ public static SqlConnectionEncryptOption Optional => throw null;
+
+ ///
+ public static SqlConnectionEncryptOption Mandatory => throw null;
+
+ ///
+ public static SqlConnectionEncryptOption Strict => throw null;
+
+ ///
+ public static implicit operator SqlConnectionEncryptOption(bool value) => throw null;
+
+ ///
+ public static implicit operator bool(SqlConnectionEncryptOption value) => throw null;
+
+ ///
+ public override string ToString() { throw null; }
+
+ ///
+ public override bool Equals(object obj) { throw null; }
+
+ ///
+ public override int GetHashCode() { throw null; }
+ }
///
public partial class SqlColumnEncryptionCertificateStoreProvider : Microsoft.Data.SqlClient.SqlColumnEncryptionKeyStoreProvider
{
@@ -457,6 +595,8 @@ protected SqlColumnEncryptionKeyStoreProvider() { }
public virtual byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations) { throw null; }
///
public virtual bool VerifyColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations, byte[] signature) { throw null; }
+ ///
+ public virtual System.TimeSpan? ColumnEncryptionKeyCacheTtl { get { throw null; } set { } }
}
///
public enum SqlCommandColumnEncryptionSetting
@@ -472,7 +612,6 @@ public enum SqlCommandColumnEncryptionSetting
}
///
[System.ComponentModel.DefaultEventAttribute("RecordsAffected")]
- [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.SqlCommandDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[System.ComponentModel.ToolboxItemAttribute(true)]
public sealed partial class SqlCommand : System.Data.Common.DbCommand, System.ICloneable
{
@@ -492,7 +631,6 @@ public SqlCommand(string cmdText, Microsoft.Data.SqlClient.SqlConnection connect
public Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting ColumnEncryptionSetting { get { throw null; } }
///
[System.ComponentModel.DefaultValueAttribute("")]
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.SQL.Design.SqlCommandTextEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
public override string CommandText { get { throw null; } set { } }
///
@@ -503,7 +641,6 @@ public SqlCommand(string cmdText, Microsoft.Data.SqlClient.SqlConnection connect
public override System.Data.CommandType CommandType { get { throw null; } set { } }
///
[System.ComponentModel.DefaultValueAttribute(null)]
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public new Microsoft.Data.SqlClient.SqlConnection Connection { get { throw null; } set { } }
///
protected override System.Data.Common.DbConnection DbConnection { get { throw null; } set { } }
@@ -517,6 +654,8 @@ public SqlCommand(string cmdText, Microsoft.Data.SqlClient.SqlConnection connect
[System.ComponentModel.DesignOnlyAttribute(true)]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public override bool DesignTimeVisible { get { throw null; } set { } }
+ ///
+ public bool EnableOptimizedParameterBinding { get { throw null; } set { } }
///
public new Microsoft.Data.SqlClient.SqlParameterCollection Parameters { get { throw null; } }
///
@@ -595,9 +734,13 @@ public override void Prepare() { }
[System.ComponentModel.BrowsableAttribute(false)]
[System.ComponentModel.DesignerSerializationVisibilityAttribute(0)]
public Microsoft.Data.Sql.SqlNotificationRequest Notification { get { throw null; } set { } }
+ ///
+ public void RegisterColumnEncryptionKeyStoreProvidersOnCommand(System.Collections.Generic.IDictionary customProviders) { }
///
[System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)]
public void ResetCommandTimeout() { }
+ ///
+ public SqlRetryLogicBaseProvider RetryLogicProvider { get { throw null; } set { } }
}
///
public sealed class SqlCommandBuilder : System.Data.Common.DbCommandBuilder
@@ -685,6 +828,8 @@ public SqlConnection(string connectionString, Microsoft.Data.SqlClient.SqlCreden
public static System.Collections.Generic.IDictionary> ColumnEncryptionTrustedMasterKeyPaths { get { throw null; } }
///
public static void RegisterColumnEncryptionKeyStoreProviders(System.Collections.Generic.IDictionary customProviders) { }
+ ///
+ public void RegisterColumnEncryptionKeyStoreProvidersOnConnection(System.Collections.Generic.IDictionary customProviders) { }
///
[System.ComponentModel.BrowsableAttribute(false)]
[System.ComponentModel.DesignerSerializationVisibilityAttribute(0)]
@@ -696,7 +841,7 @@ public static void RegisterColumnEncryptionKeyStoreProviders(System.Collections.
///
/// for internal test only
///
- [System.ComponentModel.DesignerSerializationVisibilityAttribute(0)]
+ [System.ComponentModel.DesignerSerializationVisibilityAttribute(0)]
internal string SQLDNSCachingSupportedState { get { throw null; } }
///
/// for internal test only
@@ -710,7 +855,6 @@ public static void RegisterColumnEncryptionKeyStoreProviders(System.Collections.
public int CommandTimeout { get { throw null; } }
///
[System.ComponentModel.DefaultValueAttribute("")]
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.SQL.Design.SqlConnectionStringEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
[System.ComponentModel.SettingsBindableAttribute(true)]
public override string ConnectionString { get { throw null; } set { } }
@@ -793,9 +937,10 @@ public void Open(SqlConnectionOverrides overrides) { }
public void ResetStatistics() { }
///
public System.Collections.IDictionary RetrieveStatistics() { throw null; }
-
///
public System.Collections.Generic.IDictionary RetrieveInternalInfo() { throw null; }
+ ///
+ public SqlRetryLogicBaseProvider RetryLogicProvider { get { throw null; } set { } }
}
///
public enum SqlConnectionColumnEncryptionSetting
@@ -866,7 +1011,7 @@ public SqlConnectionStringBuilder(string connectionString) { }
[System.ComponentModel.DisplayNameAttribute("Data Source")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
public string DataSource { get { throw null; } set { } }
-#if NETCOREAPP || NETSTANDARD21_AND_ABOVE
+#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
///
[System.ComponentModel.DisplayNameAttribute("Attestation Protocol")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
@@ -876,10 +1021,23 @@ public SqlConnectionStringBuilder(string connectionString) { }
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
public string EnclaveAttestationUrl { get { throw null; } set { } }
#endif
+ ///
+ [System.ComponentModel.DisplayNameAttribute("IP Address Preference")]
+ [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
+ public Microsoft.Data.SqlClient.SqlConnectionIPAddressPreference IPAddressPreference { get { throw null; } set { } }
///
[System.ComponentModel.DisplayNameAttribute("Encrypt")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
- public bool Encrypt { get { throw null; } set { } }
+ public SqlConnectionEncryptOption Encrypt { get { throw null; } set { } }
+ ///
+ [System.ComponentModel.DisplayNameAttribute("Host Name In Certificate")]
+ [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
+ public string HostNameInCertificate { get { throw null; } set { } }
+ ///
+ [System.ComponentModel.DisplayNameAttribute("Server Certificate")]
+ [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
+ public string ServerCertificate { get { throw null; } set { } }
+
///
[System.ComponentModel.DisplayNameAttribute("Enlist")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
@@ -888,6 +1046,10 @@ public SqlConnectionStringBuilder(string connectionString) { }
[System.ComponentModel.DisplayNameAttribute("Failover Partner")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
public string FailoverPartner { get { throw null; } set { } }
+ ///
+ [System.ComponentModel.DisplayNameAttribute("Failover Partner SPN")]
+ [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
+ public string FailoverPartnerSPN { get { throw null; } set { } }
///
[System.ComponentModel.DisplayNameAttribute("Initial Catalog")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
@@ -935,7 +1097,10 @@ public SqlConnectionStringBuilder(string connectionString) { }
[System.ComponentModel.DisplayNameAttribute("Persist Security Info")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
public bool PersistSecurityInfo { get { throw null; } set { } }
- ///
+ ///
+ [System.ComponentModel.DisplayNameAttribute("Pool Blocking Period")]
+ [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
+ public PoolBlockingPeriod PoolBlockingPeriod { get { throw null; } set { } }///
[System.ComponentModel.DisplayNameAttribute("Pooling")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
public bool Pooling { get { throw null; } set { } }
@@ -943,6 +1108,10 @@ public SqlConnectionStringBuilder(string connectionString) { }
[System.ComponentModel.DisplayNameAttribute("Replication")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
public bool Replication { get { throw null; } set { } }
+ ///
+ [System.ComponentModel.DisplayNameAttribute("Server SPN")]
+ [System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
+ public string ServerSPN { get { throw null; } set { } }
///
[System.ComponentModel.DisplayNameAttribute("Transaction Binding")]
[System.ComponentModel.RefreshPropertiesAttribute(System.ComponentModel.RefreshProperties.All)]
@@ -992,8 +1161,6 @@ public SqlCredential(string userId, System.Security.SecureString password) { }
}
///
[System.ComponentModel.DefaultEventAttribute("RowUpdated")]
- [System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.Data.VS.SqlDataAdapterDesigner, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
- [System.ComponentModel.ToolboxItemAttribute("Microsoft.VSDesigner.Data.VS.SqlDataAdapterToolboxItem, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public sealed partial class SqlDataAdapter : System.Data.Common.DbDataAdapter, System.Data.IDataAdapter, System.Data.IDbDataAdapter, System.ICloneable
{
///
@@ -1006,15 +1173,12 @@ public SqlDataAdapter(string selectCommandText, Microsoft.Data.SqlClient.SqlConn
public SqlDataAdapter(string selectCommandText, string selectConnectionString) { }
///
[System.ComponentModel.DefaultValueAttribute(null)]
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public new Microsoft.Data.SqlClient.SqlCommand DeleteCommand { get { throw null; } set { } }
///
[System.ComponentModel.DefaultValueAttribute(null)]
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public new Microsoft.Data.SqlClient.SqlCommand InsertCommand { get { throw null; } set { } }
///
[System.ComponentModel.DefaultValueAttribute(null)]
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public new Microsoft.Data.SqlClient.SqlCommand SelectCommand { get { throw null; } set { } }
System.Data.IDbCommand System.Data.IDbDataAdapter.DeleteCommand { get { throw null; } set { } }
System.Data.IDbCommand System.Data.IDbDataAdapter.InsertCommand { get { throw null; } set { } }
@@ -1024,7 +1188,6 @@ public SqlDataAdapter(string selectCommandText, string selectConnectionString) {
public override int UpdateBatchSize { get { throw null; } set { } }
///
[System.ComponentModel.DefaultValueAttribute(null)]
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.Design.DBCommandEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public new Microsoft.Data.SqlClient.SqlCommand UpdateCommand { get { throw null; } set { } }
///
public event Microsoft.Data.SqlClient.SqlRowUpdatedEventHandler RowUpdated { add { } remove { } }
@@ -1073,7 +1236,8 @@ public override void Close() { }
public override char GetChar(int i) { throw null; }
///
public override long GetChars(int i, long dataIndex, char[] buffer, int bufferIndex, int length) { throw null; }
- ///
+ ///
+ public System.Collections.ObjectModel.ReadOnlyCollection GetColumnSchema() { throw null; }///
public override string GetDataTypeName(int i) { throw null; }
///
public override System.DateTime GetDateTime(int i) { throw null; }
@@ -1273,7 +1437,9 @@ internal SqlException() { }
///
public byte State { get { throw null; } }
///
+#if !NET6_0_OR_GREATER
[System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)]
+#endif
public override void GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) { }
///
public override string ToString() { throw null; }
@@ -1472,7 +1638,6 @@ public void ResetSqlDbType() { }
public override string ToString() { throw null; }
}
///
- [System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.Data.Design.DBParametersEditor, Microsoft.VSDesigner, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[System.ComponentModel.ListBindableAttribute(false)]
public sealed partial class SqlParameterCollection : System.Data.Common.DbParameterCollection
{
@@ -1604,44 +1769,129 @@ protected override void Dispose(bool disposing) { }
///
public override void Rollback() { }
///
+#if NET6_0_OR_GREATER
+ public override void Rollback(string transactionName) { }
+#else
public void Rollback(string transactionName) { }
+#endif
+
///
+#if NET6_0_OR_GREATER
+ public override void Save(string savePointName) { }
+#else
public void Save(string savePointName) { }
+#endif
+ }
+ ///
+ public sealed class SqlRetryingEventArgs : System.EventArgs
+ {
+ ///
+ public SqlRetryingEventArgs(int retryCount, System.TimeSpan delay, System.Collections.Generic.IList exceptions) { }
+ ///
+ public int RetryCount { get { throw null; } }
+ ///
+ public System.TimeSpan Delay { get { throw null; } }
+ ///
+ public bool Cancel { get { throw null; } set { } }
+ ///
+ public System.Collections.Generic.IList Exceptions { get { throw null; } }
+ }
+ ///
+ public abstract class SqlRetryIntervalBaseEnumerator : System.Collections.Generic.IEnumerator, System.ICloneable
+ {
+ private readonly System.TimeSpan _minValue = System.TimeSpan.Zero;
+ private readonly System.TimeSpan _maxValue = System.TimeSpan.FromSeconds(120);
+ ///
+ public System.TimeSpan GapTimeInterval { get { throw null; } protected set { } }
+ ///
+ public System.TimeSpan MaxTimeInterval { get { throw null; } protected set { } }
+ ///
+ public System.TimeSpan MinTimeInterval { get { throw null; } protected set { } }
+ ///
+ public System.TimeSpan Current { get { throw null; } protected set { } }
+ object System.Collections.IEnumerator.Current { get { throw null; } }
+ ///
+ public SqlRetryIntervalBaseEnumerator() { }
+ ///
+ public SqlRetryIntervalBaseEnumerator(System.TimeSpan timeInterval, System.TimeSpan maxTime, System.TimeSpan minTime) { }
+ ///
+ public virtual void Reset() { }
+ ///
+ protected virtual void Validate(System.TimeSpan timeInterval, System.TimeSpan maxTimeInterval, System.TimeSpan minTimeInterval) { }
+ ///
+ protected abstract System.TimeSpan GetNextInterval();
+ ///
+ public virtual bool MoveNext() { throw null; }
+ ///
+ public virtual void Dispose() { }
+ ///
+ public virtual object Clone() { throw null; }
+ }
+ ///
+ public abstract class SqlRetryLogicBase : System.ICloneable
+ {
+ ///
+ public int NumberOfTries { get { throw null; } protected set { } }
+ ///
+ public int Current { get { throw null; } protected set { } }
+ ///
+ public SqlRetryIntervalBaseEnumerator RetryIntervalEnumerator { get { throw null; } protected set { } }
+ ///
+ public System.Predicate TransientPredicate { get { throw null; } protected set { } }
+ ///
+ public virtual bool RetryCondition(object sender) { throw null; }
+ ///
+ public abstract bool TryNextInterval(out System.TimeSpan intervalTime);
+ ///
+ public abstract void Reset();
+ ///
+ public virtual object Clone() { throw null; }
+ }
+ ///
+ public abstract class SqlRetryLogicBaseProvider
+ {
+ ///
+ public System.EventHandler Retrying { get { throw null; } set { } }
+ ///
+ public SqlRetryLogicBase RetryLogic { get { throw null; } protected set { } }
+ ///
+ public abstract TResult Execute(object sender, System.Func function);
+ ///
+ public abstract System.Threading.Tasks.Task ExecuteAsync(object sender, System.Func> function, System.Threading.CancellationToken cancellationToken = default);
+ ///
+ public abstract System.Threading.Tasks.Task ExecuteAsync(object sender, System.Func function, System.Threading.CancellationToken cancellationToken = default);
+ }
+ ///
+ public sealed class SqlRetryLogicOption
+ {
+ ///
+ public int NumberOfTries { get { throw null; } set { } }
+ ///
+ public System.TimeSpan DeltaTime { get { throw null; } set { } }
+ ///
+ public System.TimeSpan MinTimeInterval { get { throw null; } set { } }
+ ///
+ public System.TimeSpan MaxTimeInterval { get { throw null; } set { } }
+ ///
+ public System.Collections.Generic.IEnumerable TransientErrors { get { throw null; } set { } }
+ ///
+ public System.Predicate AuthorizedSqlCondition { get { throw null; } set { } }
+ }
+ ///
+ public sealed class SqlConfigurableRetryFactory
+ {
+ ///
+ public static SqlRetryLogicBaseProvider CreateExponentialRetryProvider(SqlRetryLogicOption retryLogicOption) { throw null; }
+ ///
+ public static SqlRetryLogicBaseProvider CreateIncrementalRetryProvider(SqlRetryLogicOption retryLogicOption) { throw null; }
+ ///
+ public static SqlRetryLogicBaseProvider CreateFixedRetryProvider(SqlRetryLogicOption retryLogicOption) { throw null; }
+ ///
+ public static SqlRetryLogicBaseProvider CreateNoneRetryProvider() { throw null; }
}
}
namespace Microsoft.Data.SqlClient.Server
{
- ///
- public enum DataAccessKind
- {
- ///
- None = 0,
- ///
- Read = 1
- }
- ///
- public enum Format
- {
- ///
- Unknown = 0,
- ///
- Native = 1,
- ///
- UserDefined = 2
- }
- ///
- public interface IBinarySerialize
- {
- ///
- void Read(System.IO.BinaryReader r);
- ///
- void Write(System.IO.BinaryWriter w);
- }
- ///
- public sealed partial class InvalidUdtException : System.SystemException
- {
- internal InvalidUdtException() { }
- }
///
public partial class SqlDataRecord : System.Data.IDataRecord
{
@@ -1812,44 +2062,6 @@ public virtual void SetValue(int ordinal, object value) { }
///
public virtual int SetValues(params object[] values) { throw null; }
}
- ///
- [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property | System.AttributeTargets.ReturnValue | System.AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
- public partial class SqlFacetAttribute : System.Attribute
- {
- ///
- public SqlFacetAttribute() { }
- ///
- public bool IsFixedLength { get { throw null; } set { } }
- ///
- public bool IsNullable { get { throw null; } set { } }
- ///
- public int MaxSize { get { throw null; } set { } }
- ///
- public int Precision { get { throw null; } set { } }
- ///
- public int Scale { get { throw null; } set { } }
- }
- ///
- [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false, Inherited = false), System.SerializableAttribute]
- public partial class SqlFunctionAttribute : System.Attribute
- {
- ///
- public SqlFunctionAttribute() { }
- ///
- public bool IsDeterministic { get { throw null; } set { } }
- ///
- public DataAccessKind DataAccess { get { throw null; } set { } }
- ///
- public SystemDataAccessKind SystemDataAccess { get { throw null; } set { } }
- ///
- public bool IsPrecise { get { throw null; } set { } }
- ///
- public string Name { get { throw null; } set { } }
- ///
- public string TableDefinition { get { throw null; } set { } }
- ///
- public string FillRowMethodName { get { throw null; } set { } }
- }
///
public sealed partial class SqlMetaData
{
@@ -1988,69 +2200,6 @@ public SqlMetaData(string name, System.Data.SqlDbType dbType, System.Type userDe
///
public static Microsoft.Data.SqlClient.Server.SqlMetaData InferFromValue(object value, string name) { throw null; }
}
- ///
- [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false, Inherited = false), System.SerializableAttribute]
- public sealed partial class SqlMethodAttribute : SqlFunctionAttribute
- {
- ///
- public SqlMethodAttribute() { }
- ///
- public bool OnNullCall { get { throw null; } set { } }
- ///
- public bool IsMutator { get { throw null; } set { } }
- ///
- public bool InvokeIfReceiverIsNull { get { throw null; } set { } }
- }
- ///
- [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
- public sealed partial class SqlUserDefinedAggregateAttribute : System.Attribute
- {
- ///
- public const int MaxByteSizeValue = 8000;
- ///
- public SqlUserDefinedAggregateAttribute(Format format) { }
- ///
- public int MaxByteSize { get { throw null; } set { } }
- ///
- public bool IsInvariantToDuplicates { get { throw null; } set { } }
- ///
- public bool IsInvariantToNulls { get { throw null; } set { } }
- ///
- public bool IsInvariantToOrder { get { throw null; } set { } }
- ///
- public bool IsNullIfEmpty { get { throw null; } set { } }
- ///
- public Format Format { get { throw null; } }
- ///
- public string Name { get { throw null; } set { } }
- }
- ///
- [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
- public sealed partial class SqlUserDefinedTypeAttribute : System.Attribute
- {
- ///
- public SqlUserDefinedTypeAttribute(Format format) { }
- ///
- public int MaxByteSize { get { throw null; } set { } }
- ///
- public bool IsFixedLength { get { throw null; } set { } }
- ///
- public bool IsByteOrdered { get { throw null; } set { } }
- ///
- public Format Format { get { throw null; } }
- ///
- public string ValidationMethodName { get { throw null; } set { } }
- ///
- public string Name { get { throw null; } set { } }
- }
- ///
- public enum SystemDataAccessKind
- {
- ///
- None = 0,
- ///
- Read = 1
- }
}
namespace Microsoft.Data.SqlClient.DataClassification
{
diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
index 9a6db6b167..41e1263abc 100644
--- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj
@@ -1,29 +1,22 @@
false
- netcoreapp2.1;netcoreapp3.1;netstandard2.0;netstandard2.1
+ net6.0;netstandard2.0;netstandard2.1netstandard2.1$(ObjFolder)$(Configuration)\$(AssemblyName)\ref\$(BinFolder)$(Configuration)\$(AssemblyName)\ref\$(OutputPath)\$(TargetFramework)\Microsoft.Data.SqlClient.xmlCore $(BaseProduct)
- Debug;Release;netcoreapp2.1-Debug;netcoreapp2.1-Release;netcoreapp3.1-Debug;netcoreapp3.1-Release
- netcoreapp
- netstandard
+ Debug;Release;
+ netcoreapp
+ netstandardAnyCPU;x64;x86
-
- $(DefineConstants);NETSTANDARD21_AND_ABOVE
-
-
- $(DefineConstants);NETCOREAPP
-
-
@@ -32,4 +25,4 @@
-
\ No newline at end of file
+
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/.editorconfig b/src/Microsoft.Data.SqlClient/netcore/src/.editorconfig
new file mode 100644
index 0000000000..ecc808aa66
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/netcore/src/.editorconfig
@@ -0,0 +1,12 @@
+# editorconfig.org
+
+# top-most EditorConfig file
+root = false
+
+[*.cs]
+
+# IDE0090: Use 'new(...)'
+csharp_style_implicit_object_creation_when_type_is_apparent = false
+
+# IDE0063: Use simple 'using' statement
+csharp_prefer_simple_using_statement = false
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.cs
deleted file mode 100644
index 33f0a6168a..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.IO;
-using System.Reflection;
-using System.Collections.Generic;
-using Microsoft.Xunit.Performance.Api;
-
-public class PerfHarness
-{
- public static int Main(string[] args)
- {
- try
- {
- using (XunitPerformanceHarness harness = new XunitPerformanceHarness(args))
- {
- foreach(var testName in GetTestAssemblies())
- {
- harness.RunBenchmarks(GetTestAssembly(testName));
- }
- }
-
- return 0;
- }
- catch (Exception ex)
- {
- Console.WriteLine("[ERROR] Benchmark execution failed.");
- Console.WriteLine($" {ex.ToString()}");
- return 1;
- }
- }
-
- private static string GetTestAssembly(string testName)
- {
- // Assume test assemblies are colocated/restored next to the PerfHarness.
- return Path.Combine(
- Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), testName);
- }
-
- private static IEnumerable GetTestAssemblies()
- {
- return Directory.EnumerateFiles(".", "*.Performance.Tests.dll");
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.csproj
deleted file mode 100644
index 0d6a6a78be..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.csproj
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
- {F5E941C8-AF2F-47AB-A066-FF25470CE382}
- Exe
- PerfRunner
- PerfRunner
- true
- false
- 0436
- true
- netstandard-Debug;netstandard-Release;netstandard1.3-Debug;netstandard1.3-Release
-
-
-
-
-
-
-
- Common\System\Diagnostics\CodeAnalysis\ExcludeFromCodeCoverageAttribute.cs
-
-
-
-
- PreserveNewest
-
-
-
\ No newline at end of file
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.runtimeconfig.json b/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.runtimeconfig.json
deleted file mode 100644
index 0e7c179be9..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/perf/PerfRunner/PerfRunner.runtimeconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "runtimeOptions": {
- "framework": {
- "name": "Microsoft.NETCore.App",
- "version": "9.9.9"
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs
index 2defe1a735..b08b41aeb2 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssApiException.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Data;
using System;
using System.Runtime.InteropServices;
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs
index 80a32e6c5a..0f479a8c62 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.GssBuffer.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.Data;
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs
index e3e3e3759b..489d1cf8a9 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Unix/System.Net.Security.Native/Interop.NetSecurityNative.cs
@@ -11,49 +11,52 @@ internal static partial class Interop
{
internal static partial class NetSecurityNative
{
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ReleaseGssBuffer")]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ReleaseGssBuffer")]
internal static extern void ReleaseGssBuffer(
IntPtr bufferPtr,
ulong length);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DisplayMinorStatus")]
+ [DllImport(Interop.Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_EnsureGssInitialized")]
+ private static extern int EnsureGssInitialized();
+
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_DisplayMinorStatus")]
internal static extern Status DisplayMinorStatus(
out Status minorStatus,
Status statusValue,
ref GssBuffer buffer);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DisplayMajorStatus")]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_DisplayMajorStatus")]
internal static extern Status DisplayMajorStatus(
out Status minorStatus,
Status statusValue,
ref GssBuffer buffer);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ImportUserName", CharSet = CharSet.Unicode)]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ImportUserName")]
internal static extern Status ImportUserName(
out Status minorStatus,
string inputName,
int inputNameByteCount,
out SafeGssNameHandle outputName);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ImportPrincipalName", CharSet = CharSet.Unicode)]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ImportPrincipalName")]
internal static extern Status ImportPrincipalName(
out Status minorStatus,
string inputName,
int inputNameByteCount,
out SafeGssNameHandle outputName);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ReleaseName")]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ReleaseName")]
internal static extern Status ReleaseName(
out Status minorStatus,
ref IntPtr inputName);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_InitiateCredSpNego")]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_InitiateCredSpNego")]
internal static extern Status InitiateCredSpNego(
out Status minorStatus,
SafeGssNameHandle desiredName,
out SafeGssCredHandle outputCredHandle);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_InitiateCredWithPassword", CharSet = CharSet.Unicode)]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_InitiateCredWithPassword")]
internal static extern Status InitiateCredWithPassword(
out Status minorStatus,
bool isNtlm,
@@ -62,12 +65,12 @@ internal static extern Status InitiateCredWithPassword(
int passwordLen,
out SafeGssCredHandle outputCredHandle);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_ReleaseCred")]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_ReleaseCred")]
internal static extern Status ReleaseCred(
out Status minorStatus,
ref IntPtr credHandle);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_InitSecContext")]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_InitSecContext")]
internal static extern Status InitSecContext(
out Status minorStatus,
SafeGssCredHandle initiatorCredHandle,
@@ -81,7 +84,7 @@ internal static extern Status InitSecContext(
out uint retFlags,
out int isNtlmUsed);
- [DllImport(Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_DeleteSecContext")]
+ [DllImport(Libraries.NetSecurityNative, EntryPoint = "NetSecurityNative_DeleteSecContext")]
internal static extern Status DeleteSecContext(
out Status minorStatus,
ref IntPtr contextHandle);
@@ -109,5 +112,17 @@ internal enum GssFlags : uint
GSS_C_EXTENDED_ERROR_FLAG = 0x4000,
GSS_C_DELEG_POLICY_FLAG = 0x8000
}
+
+ // This constructor is added to address the issue with net6 regarding
+ // Shim gss api on Linux to delay loading libgssapi_krb5.so
+ // issue https://github.com/dotnet/SqlClient/issues/1390
+ // dotnet runtime issue https://github.com/dotnet/runtime/pull/55037
+ static NetSecurityNative()
+ {
+ if (Environment.Version.Major >= 6)
+ {
+ EnsureGssInitialized();
+ }
+ }
}
}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs
index cfec6e4e44..cdb3819605 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIAuthType.cs
@@ -4,6 +4,7 @@
using System.Net.Security;
using System.Runtime.InteropServices;
+using Microsoft.Data;
namespace System.Net
{
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs
index 1f0f472d40..4152a89a7d 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPISecureChannelType.cs
@@ -4,6 +4,7 @@
using System.Net.Security;
using System.Runtime.InteropServices;
+using Microsoft.Data;
namespace System.Net
{
@@ -129,7 +130,7 @@ public unsafe int QueryContextAttributes(SafeDeleteContext phContext, Interop.Ss
}
else
{
- throw new ArgumentException(System.StringsHelper.Format(Strings.SSPIInvalidHandleType, handleType.FullName), nameof(handleType));
+ throw new ArgumentException(StringsHelper.Format(Strings.SSPIInvalidHandleType, handleType.FullName), nameof(handleType));
}
}
fixed (byte* bufferPtr = buffer)
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs
index ea8e713529..f8231f9069 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Interop/Windows/sspicli/SSPIWrapper.cs
@@ -6,6 +6,7 @@
using System.Globalization;
using System.Net.Security;
using System.Runtime.InteropServices;
+using Microsoft.Data;
namespace System.Net
{
@@ -101,7 +102,7 @@ public static SafeFreeCredentials AcquireDefaultCredential(SSPIInterface secModu
if (errorCode != 0)
{
if (NetEventSource.IsEnabled)
- NetEventSource.Error(null, System.StringsHelper.Format(Strings.net_log_operation_failed_with_error, nameof(AcquireDefaultCredential), $"0x{errorCode:X}"));
+ NetEventSource.Error(null, StringsHelper.Format(Strings.net_log_operation_failed_with_error, nameof(AcquireDefaultCredential), $"0x{errorCode:X}"));
throw new Win32Exception(errorCode);
}
return outCredential;
@@ -118,7 +119,7 @@ public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface secModu
if (errorCode != 0)
{
if (NetEventSource.IsEnabled)
- NetEventSource.Error(null, System.StringsHelper.Format(Strings.net_log_operation_failed_with_error, nameof(AcquireCredentialsHandle), $"0x{errorCode:X}"));
+ NetEventSource.Error(null, StringsHelper.Format(Strings.net_log_operation_failed_with_error, nameof(AcquireCredentialsHandle), $"0x{errorCode:X}"));
throw new Win32Exception(errorCode);
}
@@ -143,7 +144,7 @@ public static SafeFreeCredentials AcquireCredentialsHandle(SSPIInterface secModu
if (errorCode != 0)
{
if (NetEventSource.IsEnabled)
- NetEventSource.Error(null, System.StringsHelper.Format(Strings.net_log_operation_failed_with_error, nameof(AcquireCredentialsHandle), $"0x{errorCode:X}"));
+ NetEventSource.Error(null, StringsHelper.Format(Strings.net_log_operation_failed_with_error, nameof(AcquireCredentialsHandle), $"0x{errorCode:X}"));
throw new Win32Exception(errorCode);
}
@@ -359,11 +360,11 @@ private static unsafe int EncryptDecryptHelper(OP op, SSPIInterface secModule, S
{
if (errorCode == Interop.SspiCli.SEC_I_RENEGOTIATE)
{
- NetEventSource.Error(null, System.StringsHelper.Format(Strings.event_OperationReturnedSomething, op, "SEC_I_RENEGOTIATE"));
+ NetEventSource.Error(null, StringsHelper.Format(Strings.event_OperationReturnedSomething, op, "SEC_I_RENEGOTIATE"));
}
else
{
- NetEventSource.Error(null, System.StringsHelper.Format(Strings.net_log_operation_failed_with_error, op, $"0x{0:X}"));
+ NetEventSource.Error(null, StringsHelper.Format(Strings.net_log_operation_failed_with_error, op, $"0x{0:X}"));
}
}
@@ -466,7 +467,7 @@ public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteC
break;
default:
- throw new ArgumentException(System.StringsHelper.Format(Strings.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute));
+ throw new ArgumentException(StringsHelper.Format(Strings.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute));
}
SafeHandle sspiHandle = null;
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/AdapterUtil.Drivers.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/AdapterUtil.Drivers.cs
deleted file mode 100644
index 8647b4f81c..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/AdapterUtil.Drivers.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Threading;
-
-namespace Microsoft.Data.Common
-{
- internal static partial class ADP
- {
-
- internal static Timer UnsafeCreateTimer(TimerCallback callback, object state, int dueTime, int period)
- {
- // Don't capture the current ExecutionContext and its AsyncLocals onto
- // a global timer causing them to live forever
- bool restoreFlow = false;
- try
- {
- if (!ExecutionContext.IsFlowSuppressed())
- {
- ExecutionContext.SuppressFlow();
- restoreFlow = true;
- }
-
- return new Timer(callback, state, dueTime, period);
- }
- finally
- {
- // Restore the current ExecutionContext
- if (restoreFlow)
- ExecutionContext.RestoreFlow();
- }
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/AdapterUtil.cs
deleted file mode 100644
index 396d43caa6..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/AdapterUtil.cs
+++ /dev/null
@@ -1,531 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections;
-using System.Data;
-using System.Data.SqlTypes;
-using System.Diagnostics;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Security;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Transactions;
-using Microsoft.Data.SqlClient;
-
-namespace Microsoft.Data.Common
-{
- internal static partial class ADP
- {
- // NOTE: Initializing a Task in SQL CLR requires the "UNSAFE" permission set (http://msdn.microsoft.com/en-us/library/ms172338.aspx)
- // Therefore we are lazily initializing these Tasks to avoid forcing customers to use the "UNSAFE" set when they are actually using no Async features
- private static Task _trueTask;
- internal static Task TrueTask => _trueTask ?? (_trueTask = Task.FromResult(true));
-
- private static Task _falseTask;
- internal static Task FalseTask => _falseTask ?? (_falseTask = Task.FromResult(false));
-
- internal const CompareOptions DefaultCompareOptions = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase;
-
- internal const int DefaultConnectionTimeout = DbConnectionStringDefaults.ConnectTimeout;
- internal const int InfiniteConnectionTimeout = 0; // infinite connection timeout identifier in seconds
- internal const int MaxBufferAccessTokenExpiry = 600; // max duration for buffer in seconds
-
- static private void TraceException(string trace, Exception e)
- {
- Debug.Assert(null != e, "TraceException: null Exception");
- if (null != e)
- {
- SqlClientEventSource.Log.TryTraceEvent(trace, e);
- }
- }
-
- internal static void TraceExceptionAsReturnValue(Exception e)
- {
- TraceException(" '{0}'", e);
- }
-
- internal static void TraceExceptionWithoutRethrow(Exception e)
- {
- Debug.Assert(ADP.IsCatchableExceptionType(e), "Invalid exception type, should have been re-thrown!");
- TraceException(" '{0}'", e);
- }
-
- internal static ArgumentException Argument(string error)
- {
- ArgumentException e = new ArgumentException(error);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentException Argument(string error, Exception inner)
- {
- ArgumentException e = new ArgumentException(error, inner);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentException Argument(string error, string parameter)
- {
- ArgumentException e = new ArgumentException(error, parameter);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentNullException ArgumentNull(string parameter)
- {
- ArgumentNullException e = new ArgumentNullException(parameter);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentNullException ArgumentNull(string parameter, string error)
- {
- ArgumentNullException e = new ArgumentNullException(parameter, error);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentOutOfRangeException ArgumentOutOfRange(string parameterName)
- {
- ArgumentOutOfRangeException e = new ArgumentOutOfRangeException(parameterName);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentOutOfRangeException ArgumentOutOfRange(string message, string parameterName)
- {
- ArgumentOutOfRangeException e = new ArgumentOutOfRangeException(parameterName, message);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static IndexOutOfRangeException IndexOutOfRange(string error)
- {
- IndexOutOfRangeException e = new IndexOutOfRangeException(error);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static InvalidCastException InvalidCast(string error)
- {
- return InvalidCast(error, null);
- }
-
- internal static InvalidCastException InvalidCast(string error, Exception inner)
- {
- InvalidCastException e = new InvalidCastException(error, inner);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static InvalidOperationException InvalidOperation(string error)
- {
- InvalidOperationException e = new InvalidOperationException(error);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static NotSupportedException NotSupported()
- {
- NotSupportedException e = new NotSupportedException();
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static NotSupportedException NotSupported(string error)
- {
- NotSupportedException e = new NotSupportedException(error);
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- // the return value is true if the string was quoted and false if it was not
- // this allows the caller to determine if it is an error or not for the quotedString to not be quoted
- internal static bool RemoveStringQuotes(string quotePrefix, string quoteSuffix, string quotedString, out string unquotedString)
- {
- int prefixLength = quotePrefix != null ? quotePrefix.Length : 0;
- int suffixLength = quoteSuffix != null ? quoteSuffix.Length : 0;
-
- if ((suffixLength + prefixLength) == 0)
- {
- unquotedString = quotedString;
- return true;
- }
-
- if (quotedString == null)
- {
- unquotedString = quotedString;
- return false;
- }
-
- int quotedStringLength = quotedString.Length;
-
- // is the source string too short to be quoted
- if (quotedStringLength < prefixLength + suffixLength)
- {
- unquotedString = quotedString;
- return false;
- }
-
- // is the prefix present?
- if (prefixLength > 0)
- {
- if (!quotedString.StartsWith(quotePrefix, StringComparison.Ordinal))
- {
- unquotedString = quotedString;
- return false;
- }
- }
-
- // is the suffix present?
- if (suffixLength > 0)
- {
- if (!quotedString.EndsWith(quoteSuffix, StringComparison.Ordinal))
- {
- unquotedString = quotedString;
- return false;
- }
- unquotedString = quotedString.Substring(prefixLength, quotedStringLength - (prefixLength + suffixLength)).Replace(quoteSuffix + quoteSuffix, quoteSuffix);
- }
- else
- {
- unquotedString = quotedString.Substring(prefixLength, quotedStringLength - prefixLength);
- }
- return true;
- }
-
- internal static ArgumentOutOfRangeException NotSupportedEnumerationValue(Type type, string value, string method)
- {
- return ArgumentOutOfRange(System.StringsHelper.Format(Strings.ADP_NotSupportedEnumerationValue, type.Name, value, method), type.Name);
- }
-
- internal static InvalidOperationException DataAdapter(string error)
- {
- return InvalidOperation(error);
- }
-
- private static InvalidOperationException Provider(string error)
- {
- return InvalidOperation(error);
- }
-
- internal static ArgumentException InvalidMultipartName(string property, string value)
- {
- ArgumentException e = new ArgumentException(System.StringsHelper.Format(Strings.ADP_InvalidMultipartName, property, value));
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentException InvalidMultipartNameIncorrectUsageOfQuotes(string property, string value)
- {
- ArgumentException e = new ArgumentException(System.StringsHelper.Format(Strings.ADP_InvalidMultipartNameQuoteUsage, property, value));
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static ArgumentException InvalidMultipartNameToManyParts(string property, string value, int limit)
- {
- ArgumentException e = new ArgumentException(System.StringsHelper.Format(Strings.ADP_InvalidMultipartNameToManyParts, property, value, limit));
- TraceExceptionAsReturnValue(e);
- return e;
- }
-
- internal static void CheckArgumentNull(object value, string parameterName)
- {
- if (null == value)
- {
- throw ArgumentNull(parameterName);
- }
- }
-
- // only StackOverflowException & ThreadAbortException are sealed classes
- private static readonly Type s_stackOverflowType = typeof(StackOverflowException);
- private static readonly Type s_outOfMemoryType = typeof(OutOfMemoryException);
- private static readonly Type s_threadAbortType = typeof(ThreadAbortException);
- private static readonly Type s_nullReferenceType = typeof(NullReferenceException);
- private static readonly Type s_accessViolationType = typeof(AccessViolationException);
- private static readonly Type s_securityType = typeof(SecurityException);
-
- internal static bool IsCatchableExceptionType(Exception e)
- {
- // a 'catchable' exception is defined by what it is not.
- Debug.Assert(e != null, "Unexpected null exception!");
- Type type = e.GetType();
-
- return ((type != s_stackOverflowType) &&
- (type != s_outOfMemoryType) &&
- (type != s_threadAbortType) &&
- (type != s_nullReferenceType) &&
- (type != s_accessViolationType) &&
- !s_securityType.IsAssignableFrom(type));
- }
-
- internal static bool IsCatchableOrSecurityExceptionType(Exception e)
- {
- // a 'catchable' exception is defined by what it is not.
- // since IsCatchableExceptionType defined SecurityException as not 'catchable'
- // this method will return true for SecurityException has being catchable.
-
- // the other way to write this method is, but then SecurityException is checked twice
- // return ((e is SecurityException) || IsCatchableExceptionType(e));
-
- Debug.Assert(e != null, "Unexpected null exception!");
- Type type = e.GetType();
-
- return ((type != s_stackOverflowType) &&
- (type != s_outOfMemoryType) &&
- (type != s_threadAbortType) &&
- (type != s_nullReferenceType) &&
- (type != s_accessViolationType));
- }
-
- // Invalid Enumeration
- internal static ArgumentOutOfRangeException InvalidEnumerationValue(Type type, int value)
- {
- return ArgumentOutOfRange(System.StringsHelper.Format(Strings.ADP_InvalidEnumerationValue, type.Name, value.ToString(CultureInfo.InvariantCulture)), type.Name);
- }
-
- //
- // DbConnectionOptions, DataAccess
- //
- internal static ArgumentException ConnectionStringSyntax(int index)
- {
- return Argument(System.StringsHelper.Format(Strings.ADP_ConnectionStringSyntax, index));
- }
- internal static ArgumentException KeywordNotSupported(string keyword)
- {
- return Argument(System.StringsHelper.Format(Strings.ADP_KeywordNotSupported, keyword));
- }
- internal static ArgumentException ConvertFailed(Type fromType, Type toType, Exception innerException)
- {
- return ADP.Argument(System.StringsHelper.Format(Strings.SqlConvert_ConvertFailed, fromType.FullName, toType.FullName), innerException);
- }
-
- //
- // DbConnectionOptions, DataAccess, SqlClient
- //
- internal static Exception InvalidConnectionOptionValue(string key)
- {
- return InvalidConnectionOptionValue(key, null);
- }
- internal static Exception InvalidConnectionOptionValue(string key, Exception inner)
- {
- return Argument(System.StringsHelper.Format(Strings.ADP_InvalidConnectionOptionValue, key), inner);
- }
- static internal InvalidOperationException InvalidDataDirectory()
- {
- InvalidOperationException e = new InvalidOperationException(Strings.ADP_InvalidDataDirectory);
- return e;
- }
-
- //
- // Generic Data Provider Collection
- //
- internal static ArgumentException CollectionRemoveInvalidObject(Type itemType, ICollection collection)
- {
- return Argument(System.StringsHelper.Format(Strings.ADP_CollectionRemoveInvalidObject, itemType.Name, collection.GetType().Name));
- }
- internal static ArgumentNullException CollectionNullValue(string parameter, Type collection, Type itemType)
- {
- return ArgumentNull(parameter, System.StringsHelper.Format(Strings.ADP_CollectionNullValue, collection.Name, itemType.Name));
- }
- internal static IndexOutOfRangeException CollectionIndexInt32(int index, Type collection, int count)
- {
- return IndexOutOfRange(System.StringsHelper.Format(Strings.ADP_CollectionIndexInt32, index.ToString(CultureInfo.InvariantCulture), collection.Name, count.ToString(CultureInfo.InvariantCulture)));
- }
- internal static IndexOutOfRangeException CollectionIndexString(Type itemType, string propertyName, string propertyValue, Type collection)
- {
- return IndexOutOfRange(System.StringsHelper.Format(Strings.ADP_CollectionIndexString, itemType.Name, propertyName, propertyValue, collection.Name));
- }
- internal static InvalidCastException CollectionInvalidType(Type collection, Type itemType, object invalidValue)
- {
- return InvalidCast(System.StringsHelper.Format(Strings.ADP_CollectionInvalidType, collection.Name, itemType.Name, invalidValue.GetType().Name));
- }
-
- //
- // DbConnection
- //
- private static string ConnectionStateMsg(ConnectionState state)
- {
- switch (state)
- {
- case (ConnectionState.Closed):
- case (ConnectionState.Connecting | ConnectionState.Broken): // treated the same as closed
- return Strings.ADP_ConnectionStateMsg_Closed;
- case (ConnectionState.Connecting):
- return Strings.ADP_ConnectionStateMsg_Connecting;
- case (ConnectionState.Open):
- return Strings.ADP_ConnectionStateMsg_Open;
- case (ConnectionState.Open | ConnectionState.Executing):
- return Strings.ADP_ConnectionStateMsg_OpenExecuting;
- case (ConnectionState.Open | ConnectionState.Fetching):
- return Strings.ADP_ConnectionStateMsg_OpenFetching;
- default:
- return System.StringsHelper.Format(Strings.ADP_ConnectionStateMsg, state.ToString());
- }
- }
-
- //
- // : Stream
- //
- internal static Exception StreamClosed([CallerMemberName] string method = "")
- {
- return InvalidOperation(System.StringsHelper.Format(Strings.ADP_StreamClosed, method));
- }
-
- internal static string BuildQuotedString(string quotePrefix, string quoteSuffix, string unQuotedString)
- {
- var resultString = new StringBuilder();
- if (!string.IsNullOrEmpty(quotePrefix))
- {
- resultString.Append(quotePrefix);
- }
-
- // Assuming that the suffix is escaped by doubling it. i.e. foo"bar becomes "foo""bar".
- if (!string.IsNullOrEmpty(quoteSuffix))
- {
- resultString.Append(unQuotedString.Replace(quoteSuffix, quoteSuffix + quoteSuffix));
- resultString.Append(quoteSuffix);
- }
- else
- {
- resultString.Append(unQuotedString);
- }
-
- return resultString.ToString();
- }
-
- static internal string BuildMultiPartName(string[] strings)
- {
- StringBuilder bld = new StringBuilder();
- // Assume we want to build a full multi-part name with all parts except trimming separators for
- // leading empty names (null or empty strings, but not whitespace). Separators in the middle
- // should be added, even if the name part is null/empty, to maintain proper location of the parts.
- for (int i = 0; i < strings.Length; i++)
- {
- if (0 < bld.Length)
- {
- bld.Append('.');
- }
- if (null != strings[i] && 0 != strings[i].Length)
- {
- bld.Append(BuildQuotedString("[", "]", strings[i]));
- }
- }
- return bld.ToString();
- }
-
- //
- // Generic Data Provider Collection
- //
- internal static ArgumentException ParametersIsNotParent(Type parameterType, ICollection collection)
- {
- return Argument(System.StringsHelper.Format(Strings.ADP_CollectionIsNotParent, parameterType.Name, collection.GetType().Name));
- }
- internal static ArgumentException ParametersIsParent(Type parameterType, ICollection collection)
- {
- return Argument(System.StringsHelper.Format(Strings.ADP_CollectionIsNotParent, parameterType.Name, collection.GetType().Name));
- }
-
-
- internal enum InternalErrorCode
- {
- UnpooledObjectHasOwner = 0,
- UnpooledObjectHasWrongOwner = 1,
- PushingObjectSecondTime = 2,
- PooledObjectHasOwner = 3,
- PooledObjectInPoolMoreThanOnce = 4,
- CreateObjectReturnedNull = 5,
- NewObjectCannotBePooled = 6,
- NonPooledObjectUsedMoreThanOnce = 7,
- AttemptingToPoolOnRestrictedToken = 8,
- // ConnectionOptionsInUse = 9,
- ConvertSidToStringSidWReturnedNull = 10,
- // UnexpectedTransactedObject = 11,
- AttemptingToConstructReferenceCollectionOnStaticObject = 12,
- AttemptingToEnlistTwice = 13,
- CreateReferenceCollectionReturnedNull = 14,
- PooledObjectWithoutPool = 15,
- UnexpectedWaitAnyResult = 16,
- SynchronousConnectReturnedPending = 17,
- CompletedConnectReturnedPending = 18,
-
- NameValuePairNext = 20,
- InvalidParserState1 = 21,
- InvalidParserState2 = 22,
- InvalidParserState3 = 23,
-
- InvalidBuffer = 30,
-
- UnimplementedSMIMethod = 40,
- InvalidSmiCall = 41,
-
- SqlDependencyObtainProcessDispatcherFailureObjectHandle = 50,
- SqlDependencyProcessDispatcherFailureCreateInstance = 51,
- SqlDependencyProcessDispatcherFailureAppDomain = 52,
- SqlDependencyCommandHashIsNotAssociatedWithNotification = 53,
-
- UnknownTransactionFailure = 60,
- }
-
- internal static Exception InternalError(InternalErrorCode internalError)
- {
- return InvalidOperation(System.StringsHelper.Format(Strings.ADP_InternalProviderError, (int)internalError));
- }
-
- //
- // : DbDataReader
- //
- internal static Exception DataReaderClosed([CallerMemberName] string method = "")
- {
- return InvalidOperation(System.StringsHelper.Format(Strings.ADP_DataReaderClosed, method));
- }
- internal static ArgumentOutOfRangeException InvalidSourceBufferIndex(int maxLen, long srcOffset, string parameterName)
- {
- return ArgumentOutOfRange(System.StringsHelper.Format(Strings.ADP_InvalidSourceBufferIndex, maxLen.ToString(CultureInfo.InvariantCulture), srcOffset.ToString(CultureInfo.InvariantCulture)), parameterName);
- }
- internal static ArgumentOutOfRangeException InvalidDestinationBufferIndex(int maxLen, int dstOffset, string parameterName)
- {
- return ArgumentOutOfRange(System.StringsHelper.Format(Strings.ADP_InvalidDestinationBufferIndex, maxLen.ToString(CultureInfo.InvariantCulture), dstOffset.ToString(CultureInfo.InvariantCulture)), parameterName);
- }
- internal static IndexOutOfRangeException InvalidBufferSizeOrIndex(int numBytes, int bufferIndex)
- {
- return IndexOutOfRange(System.StringsHelper.Format(Strings.SQL_InvalidBufferSizeOrIndex, numBytes.ToString(CultureInfo.InvariantCulture), bufferIndex.ToString(CultureInfo.InvariantCulture)));
- }
- internal static Exception InvalidDataLength(long length)
- {
- return IndexOutOfRange(System.StringsHelper.Format(Strings.SQL_InvalidDataLength, length.ToString(CultureInfo.InvariantCulture)));
- }
-
- internal static bool CompareInsensitiveInvariant(string strvalue, string strconst) =>
- 0 == CultureInfo.InvariantCulture.CompareInfo.Compare(strvalue, strconst, CompareOptions.IgnoreCase);
-
- internal static int DstCompare(string strA, string strB) => CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, ADP.DefaultCompareOptions);
-
- internal static bool IsEmptyArray(string[] array) => (null == array) || (0 == array.Length);
-
- internal static bool IsNull(object value)
- {
- if ((null == value) || (DBNull.Value == value))
- {
- return true;
- }
- INullable nullable = (value as INullable);
- return ((null != nullable) && nullable.IsNull);
- }
-
- internal static Exception InvalidSeekOrigin(string parameterName)
- {
- return ArgumentOutOfRange(Strings.ADP_InvalidSeekOrigin, parameterName);
- }
-
- internal static void SetCurrentTransaction(Transaction transaction)
- {
- Transaction.Current = transaction;
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/BasicFieldNameLookup.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/BasicFieldNameLookup.cs
deleted file mode 100644
index 6d5b5b8891..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/BasicFieldNameLookup.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Collections.Generic;
-using System.Data;
-using System.Globalization;
-using Microsoft.Data.Common;
-
-namespace Microsoft.Data.ProviderBase
-{
- internal class BasicFieldNameLookup
- {
- // Dictionary stores the index into the _fieldNames, match via case-sensitive
- private Dictionary _fieldNameLookup;
-
- // original names for linear searches when exact matches fail
- private readonly string[] _fieldNames;
-
- // By default _compareInfo is set to InvariantCulture CompareInfo
- private CompareInfo _compareInfo;
-
- public BasicFieldNameLookup(string[] fieldNames)
- {
- if (null == fieldNames)
- {
- throw ADP.ArgumentNull(nameof(fieldNames));
- }
- _fieldNames = fieldNames;
- }
-
- public BasicFieldNameLookup(System.Collections.ObjectModel.ReadOnlyCollection columnNames)
- {
- int length = columnNames.Count;
- string[] fieldNames = new string[length];
- for (int i = 0; i < length; ++i)
- {
- fieldNames[i] = columnNames[i];
- }
- _fieldNames = fieldNames;
- GenerateLookup();
- }
-
- public BasicFieldNameLookup(IDataReader reader)
- {
- int length = reader.FieldCount;
- string[] fieldNames = new string[length];
- for (int i = 0; i < length; ++i)
- {
- fieldNames[i] = reader.GetName(i);
- }
- _fieldNames = fieldNames;
- }
-
- public int GetOrdinal(string fieldName)
- {
- if (null == fieldName)
- {
- throw ADP.ArgumentNull(nameof(fieldName));
- }
- int index = IndexOf(fieldName);
- if (-1 == index)
- {
- throw ADP.IndexOutOfRange(fieldName);
- }
- return index;
- }
-
- public int IndexOfName(string fieldName)
- {
- if (null == _fieldNameLookup)
- {
- GenerateLookup();
- }
-
- int value;
- // via case sensitive search, first match with lowest ordinal matches
- return _fieldNameLookup.TryGetValue(fieldName, out value) ? value : -1;
- }
-
- public int IndexOf(string fieldName)
- {
- if (null == _fieldNameLookup)
- {
- GenerateLookup();
- }
- int index;
- // via case sensitive search, first match with lowest ordinal matches
- if (!_fieldNameLookup.TryGetValue(fieldName, out index))
- {
- // via case insensitive search, first match with lowest ordinal matches
- index = LinearIndexOf(fieldName, CompareOptions.IgnoreCase);
- if (-1 == index)
- {
- // do the slow search now (kana, width insensitive comparison)
- index = LinearIndexOf(fieldName, ADP.DefaultCompareOptions);
- }
- }
-
- return index;
- }
-
- protected virtual CompareInfo GetCompareInfo()
- {
- return CultureInfo.InvariantCulture.CompareInfo;
- }
-
- private int LinearIndexOf(string fieldName, CompareOptions compareOptions)
- {
- if (null == _compareInfo)
- {
- _compareInfo = GetCompareInfo();
- }
-
- int length = _fieldNames.Length;
- for (int i = 0; i < length; ++i)
- {
- if (0 == _compareInfo.Compare(fieldName, _fieldNames[i], compareOptions))
- {
- _fieldNameLookup[fieldName] = i; // add an exact match for the future
- return i;
- }
- }
- return -1;
- }
-
- // RTM common code for generating Dictionary from array of column names
- private void GenerateLookup()
- {
- int length = _fieldNames.Length;
- Dictionary hash = new Dictionary(length);
-
- // via case sensitive search, first match with lowest ordinal matches
- for (int i = length - 1; 0 <= i; --i)
- {
- string fieldName = _fieldNames[i];
- hash[fieldName] = i;
- }
- _fieldNameLookup = hash;
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/FieldNameLookup.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/FieldNameLookup.cs
deleted file mode 100644
index f0edbf377b..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/FieldNameLookup.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System.Data;
-using System.Globalization;
-
-namespace Microsoft.Data.ProviderBase
-{
- internal sealed class FieldNameLookup : BasicFieldNameLookup
- {
- private readonly int _defaultLocaleID;
-
- public FieldNameLookup(string[] fieldNames, int defaultLocaleID) : base(fieldNames)
- {
- _defaultLocaleID = defaultLocaleID;
- }
-
- public FieldNameLookup(System.Collections.ObjectModel.ReadOnlyCollection columnNames, int defaultLocaleID) : base(columnNames)
- {
- _defaultLocaleID = defaultLocaleID;
- }
-
- public FieldNameLookup(IDataReader reader, int defaultLocaleID) : base(reader)
- {
- _defaultLocaleID = defaultLocaleID;
- }
-
- //The compare info is specified by the server by specifying the default LocaleId.
- protected override CompareInfo GetCompareInfo()
- {
- CompareInfo compareInfo = null;
- if (-1 != _defaultLocaleID)
- {
- compareInfo = CompareInfo.GetCompareInfo(_defaultLocaleID);
- }
- if (null == compareInfo)
- {
- compareInfo = base.GetCompareInfo();
- }
- return compareInfo;
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/SQLResource.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/SQLResource.cs
deleted file mode 100644
index 9d4a0818cb..0000000000
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/SQLResource.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-
-namespace Microsoft.Data.SqlTypes
-{
- internal static class SQLResource
- {
- internal static string NullString => Strings.SqlMisc_NullString;
-
- internal static string MessageString => Strings.SqlMisc_MessageString;
-
- internal static string ArithOverflowMessage => Strings.SqlMisc_ArithOverflowMessage;
-
- internal static string DivideByZeroMessage => Strings.SqlMisc_DivideByZeroMessage;
-
- internal static string NullValueMessage => Strings.SqlMisc_NullValueMessage;
-
- internal static string TruncationMessage => Strings.SqlMisc_TruncationMessage;
-
- internal static string DateTimeOverflowMessage => Strings.SqlMisc_DateTimeOverflowMessage;
-
- internal static string ConcatDiffCollationMessage => Strings.SqlMisc_ConcatDiffCollationMessage;
-
- internal static string CompareDiffCollationMessage => Strings.SqlMisc_CompareDiffCollationMessage;
-
- internal static string InvalidFlagMessage => Strings.SqlMisc_InvalidFlagMessage;
-
- internal static string NumeToDecOverflowMessage => Strings.SqlMisc_NumeToDecOverflowMessage;
-
- internal static string ConversionOverflowMessage => Strings.SqlMisc_ConversionOverflowMessage;
-
- internal static string InvalidDateTimeMessage => Strings.SqlMisc_InvalidDateTimeMessage;
-
- internal static string TimeZoneSpecifiedMessage => Strings.SqlMisc_TimeZoneSpecifiedMessage;
-
- internal static string InvalidArraySizeMessage => Strings.SqlMisc_InvalidArraySizeMessage;
-
- internal static string InvalidPrecScaleMessage => Strings.SqlMisc_InvalidPrecScaleMessage;
-
- internal static string FormatMessage => Strings.SqlMisc_FormatMessage;
-
- internal static string NotFilledMessage => Strings.SqlMisc_NotFilledMessage;
-
- internal static string AlreadyFilledMessage => Strings.SqlMisc_AlreadyFilledMessage;
-
- internal static string ClosedXmlReaderMessage => Strings.SqlMisc_ClosedXmlReaderMessage;
-
- internal static string InvalidOpStreamClosed(string method)
- {
- return System.StringsHelper.Format(Strings.SqlMisc_InvalidOpStreamClosed, method);
- }
-
- internal static string InvalidOpStreamNonWritable(string method)
- {
- return System.StringsHelper.Format(Strings.SqlMisc_InvalidOpStreamNonWritable, method);
- }
-
- internal static string InvalidOpStreamNonReadable(string method)
- {
- return System.StringsHelper.Format(Strings.SqlMisc_InvalidOpStreamNonReadable, method);
- }
-
- internal static string InvalidOpStreamNonSeekable(string method)
- {
- return System.StringsHelper.Format(Strings.SqlMisc_InvalidOpStreamNonSeekable, method);
- }
- } // SqlResource
-} // namespace System
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs
index 1ee4cba196..df16ee4d23 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionFactory.cs
@@ -25,7 +25,7 @@ internal abstract partial class DbConnectionFactory
private static int _objectTypeCount; // EventSource counter
internal int ObjectID { get; } = Interlocked.Increment(ref _objectTypeCount);
- // s_pendingOpenNonPooled is an array of tasks used to throttle creation of non-pooled connections to
+ // s_pendingOpenNonPooled is an array of tasks used to throttle creation of non-pooled connections to
// a maximum of Environment.ProcessorCount at a time.
private static uint s_pendingOpenNonPooledNext = 0;
private static Task[] s_pendingOpenNonPooled = new Task[Environment.ProcessorCount];
@@ -49,8 +49,7 @@ abstract public DbProviderFactory ProviderFactory
public void ClearAllPools()
{
- long scopeID = SqlClientEventSource.Log.TryScopeEnterEvent(" connectionPoolGroups = _connectionPoolGroups;
foreach (KeyValuePair entry in connectionPoolGroups)
@@ -62,17 +61,12 @@ public void ClearAllPools()
}
}
}
- finally
- {
- SqlClientEventSource.Log.TryScopeLeaveEvent(scopeID);
- }
}
public void ClearPool(DbConnection connection)
{
ADP.CheckArgumentNull(connection, nameof(connection));
- long scopeID = SqlClientEventSource.Log.TryScopeEnterEvent(" {0}", GetObjectId(connection));
- try
+ using (TryEventScope.Create(" {0}", GetObjectId(connection)))
{
DbConnectionPoolGroup poolGroup = GetConnectionPoolGroup(connection);
if (null != poolGroup)
@@ -80,30 +74,20 @@ public void ClearPool(DbConnection connection)
poolGroup.Clear();
}
}
- finally
- {
- SqlClientEventSource.Log.TryScopeLeaveEvent(scopeID);
- }
}
public void ClearPool(DbConnectionPoolKey key)
{
Debug.Assert(key != null, "key cannot be null");
ADP.CheckArgumentNull(key.ConnectionString, nameof(key) + "." + nameof(key.ConnectionString));
- long scopeID = SqlClientEventSource.Log.TryScopeEnterEvent(" connectionString");
- try
+ using (TryEventScope.Create(" connectionString"))
{
- DbConnectionPoolGroup poolGroup;
Dictionary connectionPoolGroups = _connectionPoolGroups;
- if (connectionPoolGroups.TryGetValue(key, out poolGroup))
+ if (connectionPoolGroups.TryGetValue(key, out DbConnectionPoolGroup poolGroup))
{
poolGroup.Clear();
}
}
- finally
- {
- SqlClientEventSource.Log.TryScopeLeaveEvent(scopeID);
- }
}
internal virtual DbConnectionPoolProviderInfo CreateConnectionPoolProviderInfo(DbConnectionOptions connectionOptions)
@@ -124,6 +108,7 @@ internal DbConnectionInternal CreateNonPooledConnection(DbConnection owningConne
DbConnectionInternal newConnection = CreateConnection(connectionOptions, poolKey, poolGroupProviderInfo, null, owningConnection, userOptions);
if (null != newConnection)
{
+ SqlClientEventSource.Log.HardConnectRequest();
newConnection.MakeNonPooledObject(owningConnection);
}
SqlClientEventSource.Log.TryTraceEvent(" {0}, Non-pooled database connection created.", ObjectID);
@@ -138,6 +123,7 @@ internal DbConnectionInternal CreatePooledConnection(DbConnectionPool pool, DbCo
DbConnectionInternal newConnection = CreateConnection(options, poolKey, poolGroupProviderInfo, pool, owningObject, userOptions);
if (null != newConnection)
{
+ SqlClientEventSource.Log.HardConnectRequest();
newConnection.MakePooledConnection(pool);
}
SqlClientEventSource.Log.TryTraceEvent(" {0}, Pooled database connection created.", ObjectID);
@@ -281,6 +267,7 @@ internal DbConnectionPoolGroup GetConnectionPoolGroup(DbConnectionPoolKey key, D
// lock prevents race condition with PruneConnectionPoolGroups
newConnectionPoolGroups.Add(key, newConnectionPoolGroup);
+ SqlClientEventSource.Log.EnterActiveConnectionPoolGroup();
connectionPoolGroup = newConnectionPoolGroup;
_connectionPoolGroups = newConnectionPoolGroups;
}
@@ -304,7 +291,7 @@ private void PruneConnectionPoolGroups(object state)
{
// when debugging this method, expect multiple threads at the same time
SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}", ObjectID);
-
+
// First, walk the pool release list and attempt to clear each
// pool, when the pool is finally empty, we dispose of it. If the
// pool isn't empty, it's because there are active connections or
@@ -324,6 +311,7 @@ private void PruneConnectionPoolGroups(object state)
{
_poolsToRelease.Remove(pool);
SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, ReleasePool={1}", ObjectID, pool.ObjectID);
+ SqlClientEventSource.Log.ExitInactiveConnectionPool();
}
}
}
@@ -348,6 +336,7 @@ private void PruneConnectionPoolGroups(object state)
{
_poolGroupsToRelease.Remove(poolGroup);
SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, ReleasePoolGroup={1}", ObjectID, poolGroup.ObjectID);
+ SqlClientEventSource.Log.ExitInactiveConnectionPoolGroup();
}
}
}
@@ -372,7 +361,8 @@ private void PruneConnectionPoolGroups(object state)
// move idle entries from last prune pass to a queue for pending release
// otherwise process entry which may move it from active to idle
if (entry.Value.Prune())
- { // may add entries to _poolsToRelease
+ {
+ // may add entries to _poolsToRelease
QueuePoolGroupForRelease(entry.Value);
}
else
@@ -405,6 +395,8 @@ internal void QueuePoolForRelease(DbConnectionPool pool, bool clearing)
}
_poolsToRelease.Add(pool);
}
+ SqlClientEventSource.Log.EnterInactiveConnectionPool();
+ SqlClientEventSource.Log.ExitActiveConnectionPool();
}
internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup)
@@ -416,6 +408,8 @@ internal void QueuePoolGroupForRelease(DbConnectionPoolGroup poolGroup)
{
_poolGroupsToRelease.Add(poolGroup);
}
+ SqlClientEventSource.Log.EnterInactiveConnectionPoolGroup();
+ SqlClientEventSource.Log.ExitActiveConnectionPoolGroup();
}
virtual protected DbConnectionInternal CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
@@ -474,5 +468,10 @@ protected virtual DbMetaDataFactory CreateMetaDataFactory(DbConnectionInternal i
abstract internal bool SetInnerConnectionFrom(DbConnection owningObject, DbConnectionInternal to, DbConnectionInternal from);
abstract internal void SetInnerConnectionTo(DbConnection owningObject, DbConnectionInternal to);
+
+ virtual internal void Unload()
+ {
+ _pruningTimer.Dispose();
+ }
}
}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
index 0e92ed4f00..516aa9b7a9 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbConnectionInternal.cs
@@ -24,7 +24,7 @@ internal abstract partial class DbConnectionInternal
private readonly bool _hidePassword;
private readonly ConnectionState _state;
- private readonly WeakReference _owningObject = new WeakReference(null, false); // [usage must be thread safe] the owning object, when not in the pool. (both Pooled and Non-Pooled connections)
+ private readonly WeakReference _owningObject = new WeakReference(null, false); // [usage must be thread safe] the owning object, when not in the pool. (both Pooled and Non-Pooled connections)
private DbConnectionPool _connectionPool; // the pooler that the connection came from (Pooled connections only)
private DbReferenceCollection _referenceCollection; // collection of objects that we need to notify in some way when we're being deactivated
@@ -63,8 +63,7 @@ internal bool CanBePooled
{
get
{
- bool flag = (!_connectionIsDoomed && !_cannotBePooled && !_owningObject.IsAlive);
- return flag;
+ return (!_connectionIsDoomed && !_cannotBePooled && !_owningObject.TryGetTarget(out DbConnection _));
}
}
@@ -103,8 +102,7 @@ internal bool IsEmancipated
// of the pool and it's owning object is no longer around to
// return it.
- bool value = (_pooledCount < 1) && !_owningObject.IsAlive;
- return value;
+ return (_pooledCount < 1) && !_owningObject.TryGetTarget(out DbConnection _);
}
}
@@ -118,13 +116,17 @@ internal bool IsInPool
}
- protected internal object Owner
+ protected internal DbConnection Owner
{
// We use a weak reference to the owning object so we can identify when
// it has been garbage collected without throwing exceptions.
get
{
- return _owningObject.Target;
+ if (_owningObject.TryGetTarget(out DbConnection connection))
+ {
+ return connection;
+ }
+ return null;
}
}
@@ -231,6 +233,7 @@ internal void DeactivateConnection()
int activateCount = Interlocked.Decrement(ref _activateCount);
#endif // DEBUG
+ SqlClientEventSource.Log.ExitActiveConnection();
if (!_connectionIsDoomed && Pool.UseLoadBalancing)
{
@@ -275,13 +278,13 @@ protected internal virtual DataTable GetSchema(DbConnectionFactory factory, DbCo
return metaDataFactory.GetSchema(outerConnection, collectionName, restrictions);
}
- internal void MakeNonPooledObject(object owningObject)
+ internal void MakeNonPooledObject(DbConnection owningObject)
{
// Used by DbConnectionFactory to indicate that this object IS NOT part of
// a connection pool.
_connectionPool = null;
- _owningObject.Target = owningObject;
+ _owningObject.SetTarget(owningObject);
_pooledCount = -1;
}
@@ -367,14 +370,15 @@ internal void PrePush(object expectedOwner)
// ReclaimEmancipatedObjects.
//3 // The following tests are retail assertions of things we can't allow to happen.
- if (null == expectedOwner)
+ bool isAlive = _owningObject.TryGetTarget(out DbConnection connection);
+ if (expectedOwner == null)
{
- if (null != _owningObject.Target)
+ if (isAlive)
{
throw ADP.InternalError(ADP.InternalErrorCode.UnpooledObjectHasOwner); // new unpooled object has an owner
}
}
- else if (_owningObject.Target != expectedOwner)
+ else if (isAlive && connection != expectedOwner)
{
throw ADP.InternalError(ADP.InternalErrorCode.UnpooledObjectHasWrongOwner); // unpooled object has incorrect owner
}
@@ -385,10 +389,10 @@ internal void PrePush(object expectedOwner)
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Preparing to push into pool, owning connection {1}, pooledCount={2}", ObjectID, 0, _pooledCount);
_pooledCount++;
- _owningObject.Target = null; // NOTE: doing this and checking for InternalError.PooledObjectHasOwner degrades the close by 2%
+ _owningObject.SetTarget(null); // NOTE: doing this and checking for InternalError.PooledObjectHasOwner degrades the close by 2%
}
- internal void PostPop(object newOwner)
+ internal void PostPop(DbConnection newOwner)
{
// Called by DbConnectionPool right after it pulls this from it's pool, we
// take this opportunity to ensure ownership and pool counts are legit.
@@ -405,12 +409,11 @@ internal void PostPop(object newOwner)
// IMPORTANT NOTE: You must have taken a lock on the object before
// you call this method to prevent race conditions with Clear and
// ReclaimEmancipatedObjects.
-
- if (null != _owningObject.Target)
+ if (_owningObject.TryGetTarget(out DbConnection _))
{
throw ADP.InternalError(ADP.InternalErrorCode.PooledObjectHasOwner); // pooled connection already has an owner!
}
- _owningObject.Target = newOwner;
+ _owningObject.SetTarget(newOwner);
_pooledCount--;
SqlClientEventSource.Log.TryPoolerTraceEvent(" {0}, Preparing to pop from pool, owning connection {1}, pooledCount={2}", ObjectID, 0, _pooledCount);
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs
index 958dedb4e5..e7efdad252 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/ProviderBase/DbReferenceCollection.cs
@@ -14,21 +14,21 @@ internal abstract class DbReferenceCollection
private struct CollectionEntry
{
private int _tag; // information about the reference
- private WeakReference _weak; // the reference itself.
+ private WeakReference