### Install Microsoft.Data.SqlClient.Extensions.Azure Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient.Extensions/Azure/src/PackageReadme.md Commands to install the package via .NET CLI or Package Manager Console. ```bash dotnet add package Microsoft.Data.SqlClient.Extensions.Azure ``` ```powershell Install-Package Microsoft.Data.SqlClient.Extensions.Azure ``` -------------------------------- ### Install Microsoft.SqlServer.Server Package Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.SqlServer.Server/PackageReadme.md Commands to install the library via the .NET CLI or the NuGet Package Manager Console. ```bash dotnet add package Microsoft.SqlServer.Server ``` ```powershell Install-Package Microsoft.SqlServer.Server ``` -------------------------------- ### Install Microsoft.Data.SqlClient.Internal.Logging Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient.Internal/Logging/src/PackageReadme.md Commands to install the internal logging package via .NET CLI or PowerShell Package Manager. ```bash dotnet add package Microsoft.Data.SqlClient.Internal.Logging ``` ```powershell Install-Package Microsoft.Data.SqlClient.Internal.Logging ``` -------------------------------- ### Install Microsoft.Data.SqlClient Package Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient/src/PackageReadme.md Commands to install the Microsoft.Data.SqlClient NuGet package using .NET CLI or Package Manager Console. ```bash dotnet add package Microsoft.Data.SqlClient ``` ```powershell Install-Package Microsoft.Data.SqlClient ``` -------------------------------- ### Configurable Retry Logic Example Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to configure SqlRetryLogicOption, create an exponential backoff retry provider, subscribe to retry events, and apply the provider to SqlConnection and SqlCommand. ```APIDOC ## Configurable Retry Logic SqlClient includes built-in configurable retry logic for handling transient errors. The `SqlRetryLogicOption` and retry providers allow automatic retry with exponential backoff, customizable error codes, and event notifications. ### Method N/A (This is a conceptual example demonstrating configuration) ### Endpoint N/A (Applies to `SqlConnection` and `SqlCommand` objects) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```csharp using System; using Microsoft.Data.SqlClient; class Program { static void Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;Pooling=false;TrustServerCertificate=True"; // Define retry logic parameters var options = new SqlRetryLogicOption { NumberOfTries = 5, MaxTimeInterval = TimeSpan.FromSeconds(20), DeltaTime = TimeSpan.FromSeconds(1), // Custom transient error codes to retry on TransientErrors = new int[] { -2, // Timeout 4060, // Cannot open database 40197, // Azure SQL processing error 40501, // Service busy 40613, // Database unavailable 49918, // Insufficient resources 49919, // Too many create/update requests 49920 // Too many requests } }; // Create exponential backoff retry provider var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options); // Subscribe to retry events for logging/monitoring provider.Retrying += (object sender, SqlRetryingEventArgs e) => { int attempt = e.RetryCount + 1; Console.WriteLine($"Retry attempt {attempt}, delay: {e.Delay}"); if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex) { Console.WriteLine($"Error {ex.Number}: {ex.Message}"); } }; // Apply retry logic to connection using (var connection = new SqlConnection(connectionString)) { connection.RetryLogicProvider = provider; connection.Open(); // Will automatically retry on transient errors // Apply retry logic to command using (var command = connection.CreateCommand()) { command.CommandText = "SELECT * FROM Customers"; command.RetryLogicProvider = provider; using (var reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine(reader["CustomerID"]); } } } } // Access baseline transient errors for extending var baselineErrors = SqlConfigurableRetryFactory.BaselineTransientErrors; Console.WriteLine($"Baseline transient error count: {baselineErrors.Count}"); } } ``` ### Response N/A (This example focuses on client-side configuration and execution) ### Response Example N/A ``` -------------------------------- ### Diagnostic Events and Tracing with SqlClient Source: https://context7.com/dotnet/sqlclient/llms.txt This example demonstrates how to subscribe to SqlClient diagnostic events using DiagnosticListener and handle various event types like command execution and connection opening. ```APIDOC ## Diagnostic Events and Tracing SqlClient provides diagnostic events through `DiagnosticListener` for observability, distributed tracing, and custom telemetry. Version 7.0 brings strongly-typed diagnostic events to .NET Framework, achieving parity with .NET Core. ### Code Example ```csharp using System; using System.Collections.Generic; using System.Diagnostics; using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient.Diagnostics; class Program { static void Main() { // Subscribe to SqlClient diagnostic events DiagnosticListener.AllListeners.Subscribe(new DiagnosticObserver()); string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand( "SELECT TOP 5 * FROM Customers", connection)) { using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine(reader["CustomerID"]); } } } } } } class DiagnosticObserver : IObserver { public void OnNext(DiagnosticListener listener) { if (listener.Name == "Microsoft.Data.SqlClient") { listener.Subscribe(new SqlClientObserver()); } } public void OnError(Exception error) { } public void OnCompleted() { } } class SqlClientObserver : IObserver> { public void OnNext(KeyValuePair kvp) { // Handle strongly-typed diagnostic events switch (kvp.Value) { case SqlClientCommandBefore before: Console.WriteLine($"[BEFORE] Command: {before.Command.CommandText}"); break; case SqlClientCommandAfter after: Console.WriteLine($"[AFTER] Command completed"); break; case SqlClientCommandError error: Console.WriteLine($"[ERROR] {error.Exception.Message}"); break; case SqlClientConnectionOpenBefore openBefore: Console.WriteLine($"[BEFORE] Opening connection"); break; case SqlClientConnectionOpenAfter openAfter: Console.WriteLine($"[AFTER] Connection opened"); break; } } public void OnError(Exception error) { } public void OnCompleted() { } } ``` ### Explanation This code sets up an observer to listen for diagnostic events published by `Microsoft.Data.SqlClient`. The `DiagnosticObserver` filters for the `Microsoft.Data.SqlClient` listener and subscribes to its events. The `SqlClientObserver` then processes these events, differentiating between various stages of command execution and connection operations, and logs relevant information to the console. ``` -------------------------------- ### Executing Concurrent Queries with MARS in C# Source: https://context7.com/dotnet/sqlclient/llms.txt This example shows how to enable MARS in a connection string and execute nested asynchronous queries on a single connection. It requires the Microsoft.Data.SqlClient library and demonstrates reading from a vendor table while simultaneously querying associated products. ```csharp using System; using System.Data; using Microsoft.Data.SqlClient; using System.Threading.Tasks; class Program { static async Task Main() { string connectionString = "Server=localhost;Database=AdventureWorks;" + "Integrated Security=SSPI;MultipleActiveResultSets=True;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); string vendorQuery = "SELECT BusinessEntityID, Name FROM Purchasing.Vendor"; string productQuery = @"SELECT Production.Product.Name FROM Production.Product INNER JOIN Purchasing.ProductVendor ON Production.Product.ProductID = Purchasing.ProductVendor.ProductID WHERE Purchasing.ProductVendor.BusinessEntityID = @VendorId"; SqlCommand vendorCmd = new SqlCommand(vendorQuery, connection); SqlCommand productCmd = new SqlCommand(productQuery, connection); productCmd.Parameters.Add("@VendorId", SqlDbType.Int); using (SqlDataReader vendorReader = await vendorCmd.ExecuteReaderAsync()) { while (await vendorReader.ReadAsync()) { Console.WriteLine($"Vendor: {vendorReader["Name"]}"); int vendorId = (int)vendorReader["BusinessEntityID"]; productCmd.Parameters["@VendorId"].Value = vendorId; using (SqlDataReader productReader = await productCmd.ExecuteReaderAsync()) { while (await productReader.ReadAsync()) { Console.WriteLine($" Product: {productReader["Name"]}"); } } } } } } } ``` -------------------------------- ### C# Code Example Placeholder Source: https://github.com/dotnet/sqlclient/blob/main/release-notes/template/release-notes-template.md This is a placeholder for a C# code example that would typically demonstrate a feature or fix mentioned in the release notes. Specific usage details would depend on the actual code. ```csharp // Code example ``` -------------------------------- ### Manage Database Transactions with SqlTransaction in C# Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to use SqlTransaction to group SQL statements into atomic units of work. It shows how to begin a transaction, execute commands within it, commit successful operations, and roll back in case of errors. Includes examples for both default and specific isolation levels. ```csharp using System; using System.Data; using Microsoft.Data.SqlClient; class Program { static void Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // Start a local transaction SqlTransaction transaction = connection.BeginTransaction(); // Create command and assign transaction SqlCommand command = connection.CreateCommand(); command.Transaction = transaction; try { // Execute multiple operations within transaction command.CommandText = "INSERT INTO Region (RegionID, RegionDescription) VALUES (100, 'Description')"; command.ExecuteNonQuery(); command.CommandText = "INSERT INTO Region (RegionID, RegionDescription) VALUES (101, 'Description')"; command.ExecuteNonQuery(); // Commit the transaction transaction.Commit(); Console.WriteLine("Both records written successfully."); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); // Attempt to rollback try { transaction.Rollback(); Console.WriteLine("Transaction rolled back."); } catch (Exception ex2) { Console.WriteLine($"Rollback failed: {ex2.Message}"); } } } // Transaction with specific isolation level using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // Use Snapshot isolation for consistent reads using (SqlTransaction snapshotTx = connection.BeginTransaction( IsolationLevel.Snapshot)) { using (SqlCommand cmd = new SqlCommand( "SELECT * FROM Products WHERE UnitsInStock > 0", connection, snapshotTx)) { using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { Console.WriteLine($"Product: {reader["ProductName"]}"); } } } snapshotTx.Commit(); } } } } ``` -------------------------------- ### Execute SQL Statements with SqlCommand in C# Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to use SqlCommand to execute SQL statements against a SQL Server database. It covers ExecuteNonQuery for data modification, ExecuteScalar for retrieving a single value, and ExecuteReader for result sets. Includes examples of asynchronous execution and setting command timeouts. ```C# using System; using System.Data; using Microsoft.Data.SqlClient; class Program { static async Task Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); // ExecuteNonQuery - for INSERT, UPDATE, DELETE using (SqlCommand insertCmd = new SqlCommand( "INSERT INTO Region (RegionID, RegionDescription) VALUES (100, 'Test Region')", connection)) { int rowsAffected = await insertCmd.ExecuteNonQueryAsync(); Console.WriteLine($"Rows inserted: {rowsAffected}"); } // ExecuteScalar - returns first column of first row using (SqlCommand countCmd = new SqlCommand( "SELECT COUNT(*) FROM Customers", connection)) { object result = await countCmd.ExecuteScalarAsync(); Console.WriteLine($"Customer count: {result}"); } // ExecuteReader - returns multiple rows using (SqlCommand selectCmd = new SqlCommand( "SELECT TOP 5 CustomerID, CompanyName FROM Customers", connection)) { using (SqlDataReader reader = await selectCmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { Console.WriteLine($"{reader["CustomerID"]}: {reader["CompanyName"]}"); } } } // Command with timeout using (SqlCommand timeoutCmd = connection.CreateCommand()) { timeoutCmd.CommandText = "SELECT * FROM LargeTable"; timeoutCmd.CommandTimeout = 120; // 2 minutes // Execute... } } } } ``` -------------------------------- ### Install Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider via NuGet Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient/add-ons/AzureKeyVaultProvider/PackageReadme.md Installs the necessary NuGet package for integrating Azure Key Vault with Always Encrypted in .NET applications. This package provides the provider for managing encryption keys stored in Azure Key Vault. ```bash dotnet add package Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider ``` ```powershell Install-Package Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider ``` -------------------------------- ### Perform Bulk Copy with SqlBulkCopy in C# Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to use SqlBulkCopy to efficiently copy data from a SqlDataReader to a SQL Server table. It includes configurations for destination table, batch size, timeout, column mappings, and progress notifications. It also shows an example of copying data from a DataTable within a transaction. ```csharp using System; using System.Data; using Microsoft.Data.SqlClient; class Program { static void Main() { string connectionString = "Server=localhost;Database=AdventureWorks;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection sourceConnection = new SqlConnection(connectionString)) { sourceConnection.Open(); // Get source data SqlCommand sourceCommand = new SqlCommand( "SELECT ProductID, Name, ProductNumber FROM Production.Product", sourceConnection); SqlDataReader reader = sourceCommand.ExecuteReader(); using (SqlConnection destinationConnection = new SqlConnection(connectionString)) { destinationConnection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection)) { bulkCopy.DestinationTableName = "dbo.BulkCopyTarget"; bulkCopy.BatchSize = 1000; bulkCopy.BulkCopyTimeout = 600; // 10 minutes // Column mappings when source and destination differ bulkCopy.ColumnMappings.Add( new SqlBulkCopyColumnMapping("ProductID", "ProdID")); bulkCopy.ColumnMappings.Add( new SqlBulkCopyColumnMapping("Name", "ProdName")); bulkCopy.ColumnMappings.Add( new SqlBulkCopyColumnMapping("ProductNumber", "ProdNum")); // Progress notification every 100 rows bulkCopy.NotifyAfter = 100; bulkCopy.SqlRowsCopied += (sender, e) => { Console.WriteLine($"Copied {e.RowsCopied} rows..."); }; try { bulkCopy.WriteToServer(reader); Console.WriteLine("Bulk copy complete."); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } finally { reader.Close(); } } } } // Bulk copy from DataTable with transaction DataTable dataTable = CreateSampleDataTable(); using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlTransaction transaction = connection.BeginTransaction()) { using (SqlBulkCopy bulkCopy = new SqlBulkCopy( connection, SqlBulkCopyOptions.KeepIdentity, transaction)) { bulkCopy.DestinationTableName = "dbo.TargetTable"; bulkCopy.WriteToServer(dataTable); } transaction.Commit(); } } } static DataTable CreateSampleDataTable() { DataTable table = new DataTable(); table.Columns.Add("Id", typeof(int)); table.Columns.Add("Name", typeof(string)); for (int i = 0; i < 1000; i++) { table.Rows.Add(i, $"Item {i}"); } return table; } } ``` -------------------------------- ### Establish SQL Server Connection Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient/src/PackageReadme.md Demonstrates how to create and open an asynchronous connection to a SQL Server instance using a connection string. ```csharp using Microsoft.Data.SqlClient; var connectionString = "Server=myserver;Database=mydb;Integrated Security=true;"; using var connection = new SqlConnection(connectionString); await connection.OpenAsync(); Console.WriteLine("Connected successfully!"); ``` -------------------------------- ### Display application help Source: https://github.com/dotnet/sqlclient/blob/main/doc/apps/AzureAuthentication/README.md Displays the built-in help and usage information for the AzureAuthentication console application. ```bash dotnet run -- --help ``` -------------------------------- ### Run Tests with Project Reference Type Source: https://github.com/dotnet/sqlclient/blob/main/BUILDGUIDE.md Demonstrates how to run tests using the 'Project' reference type with the dotnet CLI by providing the ReferenceType property. ```bash dotnet test -p:ReferenceType=Project ... ``` -------------------------------- ### C# SqlParameter for Output Parameters Source: https://context7.com/dotnet/sqlclient/llms.txt Illustrates how to use SqlParameter to retrieve an output parameter from a stored procedure or SQL statement. This example counts customers in a specific country and returns the count. ```csharp using System; using System.Data; using Microsoft.Data.SqlClient; class Program { static void Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // Output parameter example using (SqlCommand cmd = new SqlCommand( "SELECT @Count = COUNT(*) FROM Customers WHERE Country = @Country", connection)) { cmd.Parameters.AddWithValue("@Country", "USA"); SqlParameter outputParam = new SqlParameter("@Count", SqlDbType.Int); outputParam.Direction = ParameterDirection.Output; cmd.Parameters.Add(outputParam); cmd.ExecuteNonQuery(); Console.WriteLine($"US Customers: {outputParam.Value}"); } } } } ``` -------------------------------- ### Manage Database Connections with SqlConnection Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to establish synchronous and asynchronous connections to SQL Server. It covers both SQL Server authentication and Windows Authentication (SSPI), while highlighting automatic connection pooling behavior. ```csharp using System; using Microsoft.Data.SqlClient; class Program { static async Task Main() { string connectionString = "Server=localhost;Database=Northwind;" + "User Id=myUsername;Password=myPassword;Encrypt=True;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); Console.WriteLine($"Connected to: {connection.DataSource}"); connection.Close(); } string integratedConnectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;Encrypt=True;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(integratedConnectionString)) { await connection.OpenAsync(); Console.WriteLine("Connected asynchronously with Windows Authentication"); } } } ``` -------------------------------- ### Stream Large Text Data with SqlClient Source: https://context7.com/dotnet/sqlclient/llms.txt Shows how to stream large text content from a SQL Server database using C#. This example employs CommandBehavior.SequentialAccess and SqlDataReader.GetTextReader() to read text data in chunks, preventing memory overload. ```csharp using System; using System.Data; using System.IO; using System.Threading.Tasks; using Microsoft.Data.SqlClient; class Program { private const string connectionString = "Server=localhost;Database=Demo;Integrated Security=true;TrustServerCertificate=True"; static async Task Main() { await StreamTextData(); } // Stream large text data static async Task StreamTextData() { using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); using (SqlCommand command = new SqlCommand( "SELECT [Id], [TextContent] FROM [Documents]", connection)) { using (SqlDataReader reader = await command.ExecuteReaderAsync( CommandBehavior.SequentialAccess)) { while (await reader.ReadAsync()) { int id = reader.GetInt32(0); if (!await reader.IsDBNullAsync(1)) { char[] buffer = new char[4096]; using (TextReader textReader = reader.GetTextReader(1)) { int charsRead; while ((charsRead = await textReader.ReadAsync(buffer, 0, buffer.Length)) > 0) { // Process chunk of text Console.Write(buffer, 0, charsRead); } } } } } } } } } ``` -------------------------------- ### Run Azure Authentication Tester Source: https://github.com/dotnet/sqlclient/blob/main/doc/apps/AzureAuthentication/README.md Executes the sample application to test SQL Server connectivity. The command requires a valid ADO.NET connection string, typically including an authentication method for Entra ID. ```bash dotnet run -- -c "Server=myserver.database.windows.net;Database=mydb;Authentication=ActiveDirectoryDefault" ``` -------------------------------- ### Connect to Azure SQL using Service Principal Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient.Extensions/Azure/src/PackageReadme.md Demonstrates service-to-service authentication using a ClientSecretCredential with tenant, client, and secret IDs. ```csharp using Microsoft.Data.SqlClient; using Azure.Identity; var credential = new ClientSecretCredential( tenantId: "your-tenant-id", clientId: "your-client-id", clientSecret: "your-client-secret"); var connectionString = "Server=myserver.database.windows.net;Database=mydb;"; using var connection = new SqlConnection(connectionString); connection.AccessTokenCallback = async (ctx, cancellationToken) => { var token = await credential.GetTokenAsync( new Azure.Core.TokenRequestContext(new[] { "https://database.windows.net/.default" }), cancellationToken); return new SqlAuthenticationToken(token.Token, token.ExpiresOn); }; await connection.OpenAsync(); ``` -------------------------------- ### Custom SSPI Context Provider for Integrated Authentication Source: https://context7.com/dotnet/sqlclient/llms.txt Implements a custom SSPI context provider using `NegotiateAuthentication` for integrated authentication scenarios. This allows for Kerberos ticket negotiation in non-domain environments, containers, or cross-platform setups. The `SspiContextProvider` must be set before opening the SQL connection. ```csharp #if NET6_0_OR_GREATER using System; using System.Buffers; using System.Net.Security; using Microsoft.Data.SqlClient; // Custom SSPI provider using NegotiateAuthentication class CustomSspiContextProvider : SspiContextProvider { private NegotiateAuthentication? _auth; protected override bool GenerateContext( ReadOnlySpan incomingBlob, IBufferWriter outgoingBlobWriter, SspiAuthenticationParameters authParams) { // Initialize NegotiateAuthentication on first call _auth ??= new NegotiateAuthentication( new NegotiateAuthenticationClientOptions { Package = "Negotiate", TargetName = authParams.Resource, }); // Generate authentication token NegotiateAuthenticationStatusCode statusCode; byte[]? blob = _auth.GetOutgoingBlob(incomingBlob, out statusCode); if (statusCode is not NegotiateAuthenticationStatusCode.Completed and not NegotiateAuthenticationStatusCode.ContinueNeeded) { return false; } if (blob is not null) { outgoingBlobWriter.Write(blob); } return true; } } class Program { static void Main() { using var connection = new SqlConnection( "Server=myServer;Database=myDb;Integrated Security=true;"); // Set custom SSPI provider before opening connection.SspiContextProvider = new CustomSspiContextProvider(); connection.Open(); Console.WriteLine("Connected with custom SSPI provider"); } } #endif ``` -------------------------------- ### Build the Stress Test Runner Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient/tests/StressTests/Readme.md Use the dotnet CLI to build the stress test project from the source directory. ```bash $ cd .../src/Microsoft.Data.SqlClient/tests/StressTests dotnet build SqlClient.Stress.Runner [-c ] ``` -------------------------------- ### Enable MultiSubnetFailover Default with App Context Switch Source: https://github.com/dotnet/sqlclient/blob/main/release-notes/7.0/7.0.0-preview4.md Demonstrates how to globally enable MultiSubnetFailover=true by setting the 'Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault' app context switch. This can be done programmatically in C# or declaratively in App.Config. ```csharp AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableMultiSubnetFailoverByDefault", true); ``` ```xml ``` -------------------------------- ### Azure AD (Entra ID) Authentication with Microsoft.Data.SqlClient Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates various Azure Active Directory (now Microsoft Entra ID) authentication methods for connecting to Azure SQL Database using Microsoft.Data.SqlClient. This includes Interactive, Default, Managed Identity, Service Principal, and Device Code Flow authentication. Ensure the `Microsoft.Data.SqlClient.Extensions.Azure` package is installed for Azure authentication. ```csharp // First install: dotnet add package Microsoft.Data.SqlClient.Extensions.Azure using System; using System.Threading.Tasks; using Microsoft.Data.SqlClient; using Microsoft.Identity.Client; class Program { static void Main() { // Active Directory Interactive (prompts for credentials) string interactiveConnString = "Server=myserver.database.windows.net;" + "Database=mydb;" + "Authentication=Active Directory Interactive;"; // Active Directory Default (uses Azure.Identity DefaultAzureCredential) // Works with Managed Identity, Visual Studio, Azure CLI, etc. string defaultConnString = "Server=myserver.database.windows.net;" + "Database=mydb;" + "Authentication=Active Directory Default;"; // Active Directory Managed Identity (for Azure-hosted workloads) string managedIdentityConnString = "Server=myserver.database.windows.net;" + "Database=mydb;" + "Authentication=Active Directory Managed Identity;"; // Active Directory Service Principal string servicePrincipalConnString = "Server=myserver.database.windows.net;" + "Database=mydb;" + "Authentication=Active Directory Service Principal;" + "User Id={AppId};Password={ClientSecret};"; using (SqlConnection connection = new SqlConnection(defaultConnString)) { connection.Open(); Console.WriteLine("Connected with Entra ID authentication"); } } } // Custom device code flow callback class CustomAuthExample { public static void Main() { // Register custom device code flow handler var authProvider = new ActiveDirectoryAuthenticationProvider(CustomDeviceFlowCallback); SqlAuthenticationProvider.SetProvider( SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, authProvider); string connString = "Server=myserver.database.windows.net;" + "Database=mydb;" + "Authentication=Active Directory Device Code Flow;"; using (SqlConnection connection = new SqlConnection(connString)) { connection.Open(); Console.WriteLine("Connected with custom device code flow"); } } private static Task CustomDeviceFlowCallback(DeviceCodeResult result) { // Custom handling of device code prompt Console.WriteLine(result.Message); return Task.CompletedTask; } } ``` -------------------------------- ### Run Manual Tests with Dotnet CLI Source: https://github.com/dotnet/sqlclient/blob/main/BUILDGUIDE.md Executes manual tests for the Microsoft.Data.SqlClient library using the dotnet CLI. It specifies the test project, sets the configuration to Release, and filters out failing or flaky tests. ```bash dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj" \ -p:Configuration=Release \ --filter "category!=failing&category!=flaky&category!=interactive" ``` -------------------------------- ### Perform Data Operations with SqlDataAdapter Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to use SqlDataAdapter to fill a DataSet from a SQL query, manage relationships between multiple tables, and retrieve schema information including primary keys. ```csharp using System; using System.Data; using Microsoft.Data.SqlClient; class Program { static void Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { string query = "SELECT CustomerID, CompanyName FROM dbo.Customers"; SqlDataAdapter adapter = new SqlDataAdapter(query, connection); DataSet customers = new DataSet(); adapter.Fill(customers, "Customers"); Console.WriteLine($"Loaded {customers.Tables["Customers"].Rows.Count} customers"); foreach (DataRow row in customers.Tables["Customers"].Rows) { Console.WriteLine($"{row["CustomerID"]}: {row["CompanyName"]}"); } } using (SqlConnection customerConn = new SqlConnection(connectionString)) using (SqlConnection orderConn = new SqlConnection(connectionString)) { SqlDataAdapter custAdapter = new SqlDataAdapter( "SELECT * FROM dbo.Customers", customerConn); SqlDataAdapter ordAdapter = new SqlDataAdapter( "SELECT * FROM Orders", orderConn); 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 parentRow in customerOrders.Tables["Customers"].Rows) { Console.WriteLine($"Customer: {parentRow["CustomerID"]}"); foreach (DataRow childRow in parentRow.GetChildRows(relation)) { Console.WriteLine($" Order: {childRow["OrderID"]}"); } } } using (SqlConnection connection = new SqlConnection(connectionString)) { DataSet schemaSet = new DataSet(); SqlDataAdapter adapter = new SqlDataAdapter( "SELECT * FROM dbo.Customers", connection); adapter.FillSchema(schemaSet, SchemaType.Source, "Customers"); adapter.Fill(schemaSet, "Customers"); DataTable table = schemaSet.Tables["Customers"]; Console.WriteLine($"Primary Key: {string.Join(", ", Array.ConvertAll(table.PrimaryKey, c => c.ColumnName))}"); } } } ``` -------------------------------- ### Configure and Apply SQLClient Retry Logic in C# Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to configure SqlRetryLogicOption for custom retry behavior, including the number of tries, maximum time interval, and specific transient error codes. It also shows how to create an exponential backoff retry provider and apply it to both SqlConnection and SqlCommand objects. Event handling for retrying attempts is included for logging purposes. ```csharp using System; using Microsoft.Data.SqlClient; class Program { static void Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;Pooling=false;TrustServerCertificate=True"; // Define retry logic parameters var options = new SqlRetryLogicOption { NumberOfTries = 5, MaxTimeInterval = TimeSpan.FromSeconds(20), DeltaTime = TimeSpan.FromSeconds(1), // Custom transient error codes to retry on TransientErrors = new int[] { -2, // Timeout 4060, // Cannot open database 40197, // Azure SQL processing error 40501, // Service busy 40613, // Database unavailable 49918, // Insufficient resources 49919, // Too many create/update requests 49920 // Too many requests } }; // Create exponential backoff retry provider var provider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(options); // Subscribe to retry events for logging/monitoring provider.Retrying += (object sender, SqlRetryingEventArgs e) => { int attempt = e.RetryCount + 1; Console.WriteLine($"Retry attempt {attempt}, delay: {e.Delay}"); if (e.Exceptions[e.Exceptions.Count - 1] is SqlException ex) { Console.WriteLine($"Error {ex.Number}: {ex.Message}"); } }; // Apply retry logic to connection using (var connection = new SqlConnection(connectionString)) { connection.RetryLogicProvider = provider; connection.Open(); // Will automatically retry on transient errors // Apply retry logic to command using (var command = connection.CreateCommand()) { command.CommandText = "SELECT * FROM Customers"; command.RetryLogicProvider = provider; using (var reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine(reader["CustomerID"]); } } } } // Access baseline transient errors for extending var baselineErrors = SqlConfigurableRetryFactory.BaselineTransientErrors; Console.WriteLine($"Baseline transient error count: {baselineErrors.Count}"); } } ``` -------------------------------- ### Connect to Azure SQL using DefaultAzureCredential Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient.Extensions/Azure/src/PackageReadme.md Demonstrates how to use DefaultAzureCredential to automatically authenticate with Azure SQL. This approach is recommended for environments where multiple authentication methods might be used. ```csharp using Microsoft.Data.SqlClient; using Azure.Identity; var credential = new DefaultAzureCredential(); var connectionString = "Server=myserver.database.windows.net;Database=mydb;"; using var connection = new SqlConnection(connectionString); connection.AccessTokenCallback = async (ctx, cancellationToken) => { var token = await credential.GetTokenAsync( new Azure.Core.TokenRequestContext(new[] { "https://database.windows.net/.default" }), cancellationToken); return new SqlAuthenticationToken(token.Token, token.ExpiresOn); }; await connection.OpenAsync(); ``` -------------------------------- ### C# SqlDataReader Streaming Large Binary Data with SequentialAccess Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates how to stream large binary data (like BLOBs) efficiently from SQL Server using SqlDataReader with the CommandBehavior.SequentialAccess option. This minimizes memory usage by reading data in chunks. ```csharp using System; using System.Data; using System.IO; using System.Threading.Tasks; using Microsoft.Data.SqlClient; class Program { static async Task Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); // Streaming large binary data with SequentialAccess using (SqlCommand cmd = new SqlCommand( "SELECT DocumentData FROM Documents WHERE Id = @id", connection)) { cmd.Parameters.AddWithValue("@id", 1); using (SqlDataReader reader = await cmd.ExecuteReaderAsync( CommandBehavior.SequentialAccess)) { if (await reader.ReadAsync() && !await reader.IsDBNullAsync(0)) { using (Stream dataStream = reader.GetStream(0)) using (FileStream file = new FileStream("output.bin", FileMode.Create)) { await dataStream.CopyToAsync(file); } } } } } } } ``` -------------------------------- ### Custom SSPI Context Provider for SqlConnection Source: https://github.com/dotnet/sqlclient/blob/main/release-notes/7.0/7.0.0.md Demonstrates how to set a custom SSPI context provider for integrated authentication with SqlConnection. This allows for custom Kerberos ticket negotiation or NTLM username/password authentication scenarios by supplying a custom SspiContextProvider before opening the connection. ```csharp var connection = new SqlConnection(connectionString); connection.SspiContextProvider = new MyKerberosProvider(); connection.Open(); ``` -------------------------------- ### Configure Legacy AKV Provider for Microsoft.Data.SqlClient Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient.Extensions/Abstractions/README.md This snippet shows the temporary migration path using the deprecated AKV provider package. This package is maintained for backward compatibility and transitively depends on the Azure extension package. ```xml ``` -------------------------------- ### Execute Multiple SQL Commands with SqlBatch in C# Source: https://context7.com/dotnet/sqlclient/llms.txt This C# code snippet demonstrates how to use the SqlBatch class to execute multiple SQL commands, including parameterized ones, in a single round trip to the database. It shows adding commands, executing the batch, and reading results sequentially using SqlDataReader. Requires .NET 6 or later. ```csharp #if NET6_0_OR_GREATER using System; using System.Collections.Generic; using Microsoft.Data.SqlClient; class Program { static void Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True;Encrypt=False"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (SqlBatch batch = new SqlBatch(connection)) { // Add multiple commands to the batch batch.BatchCommands.Add(new SqlBatchCommand( "SELECT COUNT(*) FROM Customers")); batch.BatchCommands.Add(new SqlBatchCommand( "SELECT COUNT(*) FROM Orders")); batch.BatchCommands.Add(new SqlBatchCommand( "SELECT COUNT(*) FROM Products")); // Execute and read all results var results = new List(); using (SqlDataReader reader = batch.ExecuteReader()) { do { while (reader.Read()) { results.Add(reader.GetInt32(0)); } } while (reader.NextResult()); } Console.WriteLine($"Customers: {results[0]}"); Console.WriteLine($"Orders: {results[1]}"); Console.WriteLine($"Products: {results[2]}"); } // Batch with parameterized commands using (SqlBatch batch = new SqlBatch(connection)) { for (int i = 0; i < 10; i++) { var cmd = new SqlBatchCommand("SELECT @value AS value"); cmd.Parameters.Add(new SqlParameter("@value", i * 10)); batch.BatchCommands.Add(cmd); } using (SqlDataReader reader = batch.ExecuteReader()) { int batchIndex = 0; do { while (reader.Read()) { Console.WriteLine($"Batch {batchIndex}: {reader.GetInt32(0)}"); } batchIndex++; } while (reader.NextResult()); } } } } } #endif ``` -------------------------------- ### Stream Large Binary Data with SqlClient Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates streaming large binary data from a SQL Server database to a file using C#. It utilizes CommandBehavior.SequentialAccess and SqlDataReader.GetStream() for efficient, non-buffered data transfer. ```csharp using System; using System.Data; using System.IO; using System.Threading.Tasks; using Microsoft.Data.SqlClient; class Program { private const string connectionString = "Server=localhost;Database=Demo;Integrated Security=true;TrustServerCertificate=True"; static async Task Main() { await StreamBinaryData(); } // Stream large binary data to file static async Task StreamBinaryData() { using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); using (SqlCommand command = new SqlCommand( "SELECT [BinaryData] FROM [LargeObjects] WHERE [Id]=@id", connection)) { command.Parameters.AddWithValue("id", 1); // SequentialAccess enables streaming using (SqlDataReader reader = await command.ExecuteReaderAsync( CommandBehavior.SequentialAccess)) { if (await reader.ReadAsync() && !await reader.IsDBNullAsync(0)) { using (Stream dataStream = reader.GetStream(0)) using (FileStream file = new FileStream("output.bin", FileMode.Create)) { await dataStream.CopyToAsync(file); } Console.WriteLine("Binary data streamed to file"); } } } } } } ``` -------------------------------- ### Run Unit Tests with Dotnet CLI Source: https://github.com/dotnet/sqlclient/blob/main/BUILDGUIDE.md Executes unit tests for the Microsoft.Data.SqlClient library using the dotnet CLI. It specifies the test project, sets the configuration to Release, and filters out failing or flaky tests. ```bash dotnet test "src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft.Data.SqlClient.UnitTests.csproj" \ -p:Configuration=Release \ --filter "category!=failing&category!=flaky&category!=interactive" ``` -------------------------------- ### Build and Pack Components with Package References Source: https://github.com/dotnet/sqlclient/blob/main/BUILDGUIDE.md Builds and packs various components of the MDS driver using dotnet CLI, specifying 'Package' as the ReferenceType for inter-component dependencies. This generates NuGet packages in the 'packages/' directory. ```bash dotnet build -t:BuildLogging,PackLogging dotnet build -t:BuildSqlServer,PackSqlServer dotnet build -t:BuildAbstractions,PackAbstractions -p:ReferenceType=Package dotnet build -t:BuildAzure,PackAzure -p:ReferenceType=Package dotnet build -t:BuildSqlClient -p:ReferenceType=Package dotnet build -t:GenerateMdsPackage dotnet build -t:BuildAKVNetCore -p:ReferenceType=Package dotnet build -t:GenerateAkvPackage ``` -------------------------------- ### C# SqlDataReader Basic Reading with Typed Accessors Source: https://context7.com/dotnet/sqlclient/llms.txt Demonstrates basic reading of a SQL Server result set using SqlDataReader with typed accessors like GetInt32, GetString, and GetDateTime. It also shows how to handle nullable columns. ```csharp using System; using System.Data; using System.IO; using System.Threading.Tasks; using Microsoft.Data.SqlClient; class Program { static async Task Main() { string connectionString = "Server=localhost;Database=Northwind;" + "Integrated Security=SSPI;TrustServerCertificate=True"; using (SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); // Basic reading with typed accessors using (SqlCommand cmd = new SqlCommand( "SELECT OrderID, CustomerID, OrderDate, Freight FROM Orders", connection)) { using (SqlDataReader reader = await cmd.ExecuteReaderAsync()) { // Get column metadata Console.WriteLine($"Columns: {reader.FieldCount}"); while (await reader.ReadAsync()) { int orderId = reader.GetInt32(0); string customerId = reader.GetString(1); DateTime orderDate = reader.GetDateTime(2); // Handle nullable columns decimal? freight = reader.IsDBNull(3) ? null : reader.GetDecimal(3); Console.WriteLine($"Order {orderId}: {customerId} on {orderDate:d}"); } } } } } } ``` -------------------------------- ### Run all tests with method names Source: https://github.com/dotnet/sqlclient/blob/main/src/Microsoft.Data.SqlClient/tests/StressTests/Readme.md Executes all tests and prints the name of each test method to the console. ```powershell > .\stresstest.exe -a SqlClient.Stress.Tests -all -printMethodName ```