共用方式為


Microsoft.Data.SqlClient 命名空間簡介

下載 ADO.NET

Microsoft.Data.SqlClient 命名空間基本上是 System.Data.SqlClient 命名空間的新版本。 Microsoft.Data.SqlClient 的 API 和回溯相容性通常會維持與 System.Data.SqlClient 相同。 若要從 System.Data.SqlClient 移轉至 Microsoft.Data.SqlClient,對大部分的應用程式而言很簡單。 對 Microsoft.Data.SqlClient 新增 NuGet 相依性,並將參考和 using 陳述式更新至 Microsoft.Data.SqlClient。

相較於 System.Data.SqlClient 較少使用的 API 中,有一些差異可能會影響某些應用程式。 如需瞭解這些差異,請參閱實用的移植速查表

API 參考資料

您可以在 .NET API 瀏覽器中查找 Microsoft.Data.SqlClient API 的詳細資料。

Microsoft.Data.SqlClient 5.2 的版本資訊

5.2 版的新功能

  • 已在 .NET Standard 上新增的 SqlDiagnosticListener 支援。 #1931
  • 已將新 RowsCopied64 屬性新增至 SqlBulkCopy#2004 閱讀詳情
  • 已將新 AccessTokenCallBack API 新增至 SqlConnection#1260 閱讀詳情
  • 已新增對 Windows 上 Encrypt on .NET 的 SuperSocketNetLib 登錄選項的支援。 #2047
  • 已新增 .NET 6+ 的 SqlBatch 支援 #1825#2223閱讀詳細資訊
  • 已新增工作負載身分驗證支援 #2159#2264
  • 已新增 .NET 的當地語系化支援 #2210
  • 已新增對喬治亞文定序的支援 #2194
  • 已新增對 Big Endian 系統的支援 #2170
  • 已新增 .NET 8 支援 #2230
  • 已在 System.Runtime.Caching 8.0.0、System.Configuration.ConfigurationManager 8.0.0 和 System.Diagnostics.DiagnosticSource 8.0.0 上新增主要 .NET 版本相依性的明確版本 #2303
  • 已新增在個別封裝檔案中產生偵錯符號的功能 #2137

已將新屬性 RowsCopied64 新增至 SqlBulkCopy

SqlBulkCopy 有支援 long 實值型別的新屬性 RowsCopied64

請注意,現有 SqlBulkCopy.RowsCopied 行為不會變更。 當值超過 int.MaxValue 時,RowsCopied 可以傳回負數。

使用方式範例:

    using (SqlConnection srcConn = new SqlConnection(srcConstr))
    using (SqlCommand srcCmd = new SqlCommand("select top 5 * from employees", srcConn))
    {
        srcConn.Open();
        using (DbDataReader reader = srcCmd.ExecuteReader())
        {
            using (SqlBulkCopy bulkcopy = new SqlBulkCopy(dstConn))
            {
                bulkcopy.DestinationTableName = dstTable;
                SqlBulkCopyColumnMappingCollection ColumnMappings = bulkcopy.ColumnMappings;

                ColumnMappings.Add("EmployeeID", "col1");
                ColumnMappings.Add("LastName", "col2");
                ColumnMappings.Add("FirstName", "col3");

                bulkcopy.WriteToServer(reader);
                long rowsCopied = bulkcopy.RowsCopied64;
            }
        }
    }

已將新屬性 AccessTokenCallBack 新增至 SqlConnection

SqlConnection 支援 TokenCredential 驗證,方法是引進新的 AccessTokenCallBack 屬性做為 Func<SqlAuthenticationParameters, CancellationToken,Task<SqlAuthenticationToken>> 委派,以傳回同盟驗證存取權杖。

使用方式範例:

using Microsoft.Data.SqlClient;
using Azure.Identity;

const string defaultScopeSuffix = "/.default";
string connectionString = GetConnectionString();
DefaultAzureCredential credential = new();
using SqlConnection connection = new(connectionString);

connection.AccessTokenCallback = async (authParams, cancellationToken) =>
{
    string scope = authParams.Resource.EndsWith(defaultScopeSuffix)
        ? authParams.Resource
        : $"{authParams.Resource}{defaultScopeSuffix}";
    AccessToken token = await cred.GetTokenAsync(
        new TokenRequestContext([scope]),
        cancellationToken);

    return new SqlAuthenticationToken(token.Token, token.ExpiresOn);
}

connection.Open();
Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
Console.WriteLine("State: {0}", connection.State);

SqlBatch API

使用方式範例:

using Microsoft.Data.SqlClient;

class Program
{
    static void Main()
    {
        string str = "Data Source=(local);Initial Catalog=Northwind;"
        + "Integrated Security=SSPI;Encrypt=False";
        RunBatch(str);
    }

    static void RunBatch(string connString)
    {
        using var connection = new SqlConnection(connString);
        connection.Open();

        var batch = new SqlBatch(connection);

        const int count = 10;
        const string parameterName = "parameter";
        for (int i = 0; i < count; i++)
        {
            var batchCommand = new SqlBatchCommand($"SELECT @{parameterName} as value");
            batchCommand.Parameters.Add(new SqlParameter(parameterName, i));
            batch.BatchCommands.Add(batchCommand);
        }

        // Optionally Prepare
        batch.Prepare();

        var results = new List<int>(count);
        using (SqlDataReader reader = batch.ExecuteReader())
        {
            do
            {
                while (reader.Read())
                {
                    results.Add(reader.GetFieldValue<int>(0));
                }
            } while (reader.NextResult());
        }
        Console.WriteLine(string.Join(", ", results));
    }
}

5.2 版目標平台支援

  • .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)

GitHub 存放庫提供包括相依性在內的完整版本資訊:5.2 版本資訊

5.1 版的中斷性變更

5.1 版的新功能

  • 新增 DateOnlyTimeOnlySqlParameter 值及 GetFieldValue 的支援。 #1813
  • 新增對 .NET Core 和 SNI Native 的 TLS 1.3 支援。 #1821
  • 新增 Encrypt=MandatoryEncrypt=StrictServerCertificate 設定。 #1822 閱讀詳情
  • 新增以 .NET Framework 為目標時的 Windows ARM64 支援。 #1828

伺服器憑證

ServerCertificate 連線設定的預設值是空字串。 當 Encrypt 設為 MandatoryStrict 時,ServerCertificate 可用來指定檔案系統上與伺服器 TLS/SSL 憑證相符的憑證檔案路徑。 指定的憑證必須完全一致才會有效。 接受的憑證格式為 PEMDERCER。 以下是使用範例︰

"Data Source=...;Encrypt=Strict;ServerCertificate=C:\\certificates\\server.cer"

5.1 版目標平台支援

  • .NET Framework 4.6.2+ (Windows x86、Windows x64)
  • .NET 6.0+ (Windows x86、Windows x64、Windows ARM64、Windows Azure Resource Manager、Linux、macOS)
  • .NET Standard 2.0+ (Windows x86、Windows x64、Windows ARM64、Windows ARM、Linux、macOS)

GitHub 存放庫提供包括相依性在內的完整版本資訊:5.1 版本資訊

Microsoft.Data.SqlClient 5.0 的版本資訊

5.0 版的中斷性變更

  • 卸除 .NET Framework 4.6.1 的支援 #1574
  • 新增 Microsoft.SqlServer.Server 套件的相依性。 如果您的應用程式參考該命名空間,而且仍有套件 (直接或間接) 參考來自 .NET Core 的 System.Data.SqlClient,這個新的相依性可能會造成命名空間衝突。
  • Microsoft.Data.SqlClient.Server 命名空間卸除類別,並取代為 Microsoft.SqlServer.Server 套件的支援類型。#1585。 受影響的類別和列舉如下:
    • 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
    • (列舉) Microsoft.Data.SqlClient.Server.DataAccessKind -> Microsoft.SqlServer.Server.DataAccessKind
    • (列舉) Microsoft.Data.SqlClient.Server.Format -> Microsoft.SqlServer.Server.Format
    • (列舉) Microsoft.Data.SqlClient.Server.SystemDataAccessKind -> Microsoft.SqlServer.Server.SystemDataAccessKind

5.0 版的新功能

  • 新增 TDS8 支援。 若要使用 TDS 8,使用者應該在連接字串中指定 Encrypt=Strict。 #1608 閱讀詳情
  • 新增對連線指定伺服器 SPN 和容錯移轉伺服器 SPN 的支援。 #1607 閱讀詳情
  • 新增在 Windows 上以 .NET Core 為目標時的別名支援。 #1588 閱讀詳情
  • 新增 SqlDataSourceEnumerator。 #1430閱讀詳情
  • 新增 AppContext 切換,用於隱藏不安全的 TLS 警告。 #1457閱讀詳情

TDS 8 增強式安全性

若要使用 TDS 8,請在連接字串中指定 Encrypt=Strict。 Strict 模式會停用 TrustServerCertificate (在 Strict 模式下一律視為 False)。 新增 HostNameInCertificate 以協助某些 Strict 模式案例。 TDS 8 會開始,並在安全且加密的 TLS 連線內繼續所有伺服器通訊。

新增 Encrypt 值以釐清連線加密行為。 Encrypt=Mandatory 相當於 Encrypt=True,會在 TDS 連線交涉期間加密連線。 Encrypt=Optional 相當於 Encrypt=False,只有在伺服器告知用戶端在 TDS 連線交涉期間須加密時,才會加密連線。

如需關於將伺服器連線加密的詳細資訊,請參閱加密和憑證驗證

如果伺服器具有伺服器憑證,且名稱或替代主體名稱與用戶端用來識別伺服器的名稱 (例如 DNS 別名) 不同,當使用別名透過加密連線到該伺服器時,可以在連接字串中指定 HostNameInCertificate。 使用方式範例:HostNameInCertificate=MyDnsAliasName

伺服器 SPN

在具有唯一網域/樹系拓撲的環境中連線時,您可能會對伺服器 SPN 有特定需求。 ServerSPN/Server SPN and FailoverServerSPN/Failover Server SPN 連接字串設定,可用來覆寫網域環境中進行整合式驗證期間所使用的自動產生伺服器 SPN

SQL 別名支援

使用者可以使用 SQL Server 組態管理員來設定別名。 這些別名會儲存在 Windows 登錄中,且在以 .NET Framework 為目標時已受到支援。 在 Windows 上以 .NET 或 .NET Core 為目標時,此版本提供別名支援。

SQL 資料來源列舉程式支援

提供列舉區域網路內所有可用之 SQL Server 執行個體的機制。

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("============================");  
    }  
  }  

隱藏不安全的 TLS 警告

如果使用低於 1.2 的 TLS 版本與伺服器交涉,主控台上就會輸出安全性警告。 在應用程式啟動期間啟用下列 AppContext 切換,Encrypt = false 時即可在 SQL 連線上隱藏此警告:

Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning

5.0 版目標平台支援

  • .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)

GitHub 存放庫提供包括相依性在內的完整版本資訊:5.0 版本資訊

Microsoft.Data.SqlClient 4.1 的版本資訊

GitHub 存放庫提供包括相依性在內的完整版本資訊:4.1 版本資訊

4.1 版的新功能

引進證明通訊協定 None

允許在連接字串中使用名為 None 的新證明通訊協定。 此通訊協定可讓使用者放棄對 VBS 記憶體保護區進行記憶體保護區證明。 若設定此通訊協定,記憶體保護區證明 URL 屬性是選用的。

連接字串範例:

//Attestation protocol NONE with no URL
"Data Source = {server}; Initial Catalog = {db}; Column Encryption Setting = Enabled; Attestation Protocol = None;"

4.1 版目標平台支援

  • .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)

Microsoft.Data.SqlClient 4.0 的版本資訊

GitHub 存放庫提供包括相依性在內的完整版本資訊:4.0 版本資訊

4.0 版的中斷性變更

  • 預設情況下會將 Encrypt 連接字串屬性變更為 true#1210 閱讀詳情
  • 驅動程式現在會擲回 SqlException,取代 Active Directory 驗證模式的 AggregateException#1213
  • 從 .NET Framework 卸除已淘汰的 Asynchronous Processing 連線屬性。 #1148
  • 移除 Configurable Retry Logic 安全切換。 #1254 閱讀詳情
  • 卸除 .NET Core 2.1 的支援 #1272
  • [.NET Framework] 使用 Active Directory Integrated 驗證時,如果連接字串中提供使用者識別碼,則不會擲回例外狀況#1359

4.0 版的新功能

將 Encrypt 預設值設定為 true

Encrypt 連線設定的預設值已從 false 變更為 true。 隨著雲端資料庫的使用量不斷增加,以及對確保這些連線安全的需求出現,是時候推出這項回溯相容性中斷性變更了。

確保需要加密時連線會失敗

在用戶端加密程式庫已停用或無法使用的情況下,當 Encrypt 設為 true 或伺服器要求加密時,可能會進行未加密連線。

使用系統預設通訊協定的應用程式環境切換

驅動程式不支援 TLS 1.3,因此已預設從支援的通訊協定清單中移除它。 使用者可啟用以下應用程式環境切換,切換回強制使用作業系統的用戶端通訊協定:

Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols

啟用最佳化參數繫結

Microsoft.Data.SqlClient 引進新的 SqlCommand API (EnableOptimizedParameterBinding),可改善具有大量參數的查詢效能。 預設會停用此屬性。 若設定為 true,則執行命令時,系統不會將參數名稱傳送至 SQL Server 執行個體。

public class SqlCommand
{
    public bool EnableOptimizedParameterBinding { get; set; }
}

移除可設定的重試邏輯安全切換

不再需要應用程式環境切換「Switch.Microsoft.Data.SqlClient.EnableRetryLogic」,即可使用可設定的重試邏輯功能。 生產環境現已支援此功能。 此功能的預設行為會維持為非重試原則,用戶端應用程式必須覆寫此原則才能啟用重試。

SqlLocalDb 共用執行個體支援

使用受控 SNI 時,現在支援 SqlLocalDb 共用執行個體。

  • 可能的案例:
    • (localdb)\. (連線至 SqlLocalDb 的預設執行個體)
    • (localdb)\<named instance>
    • (localdb)\.\<shared instance name> (*新增的支援)

XmlReaderTextReaderStream 類型的 GetFieldValueAsync<T>GetFieldValue<T> 支援

使用 GetFieldValueAsync<T>GetFieldValue<T> 時,現在支援 XmlReaderTextReaderStream 類型。

使用方式範例:

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<Stream>(1))
                {
                    // Continue to read from stream
                }
            }
        }
    }
}

4.0 版目標平台支援

  • .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)

Microsoft.Data.SqlClient 3.0 的版本資訊

GitHub 存放庫提供包括相依性在內的完整版本資訊:3.0 版本資訊

3.0 版的中斷性變更

  • 支援的最低 .NET Framework 版本已提高到 v4.6.1。 不再支援 .NET Framework v4.6.0。 #899
  • 針對使用者指派的受控識別User Id 連線屬性現在需使用 Client Id 而非 Object Id#1010 閱讀詳情
  • SqlDataReader 現在會傳回 DBNull 值,而不是空的 byte[]。 設定 AppContext 切換 Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior,即可啟用舊版行為 #998 閱讀詳情

3.0 版的新功能

可設定的重試邏輯

這項新功能引進可設定的用戶端應用程式支援,可重試「暫時性」或「可重試」錯誤。 您可透過程式碼或應用程式組態檔來進行設定,且可套用重試作業來開啟連線或執行命令。 此功能預設為停用,目前為預覽版。 若要啟用此支援,用戶端應用程式必須開啟下列安全切換:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.EnableRetryLogic", true);

啟用 .NET AppContext 切換後,就可以針對 SqlConnectionSqlCommand 分別定義重試邏輯原則,或使用各種自訂選項一起定義。

SqlConnectionSqlCommand 中引進新的公用 API,用於註冊自訂 SqlRetryLogicBaseProvider 實作:

public SqlConnection
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

public SqlCommand
{
    public SqlRetryLogicBaseProvider RetryLogicProvider;
}

如需 API 使用範例,請前往:

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.");
    }
}
/// 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();
    }
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)
};

此外也引進了新的組態區段,可從組態檔執行相同的註冊,而不需要修改現有的程式碼:

<section name="SqlConfigurableRetryLogicConnection"
            type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection, Microsoft.Data.SqlClient"/>

<section name="SqlConfigurableRetryLogicCommand"
            type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>

以下為在組態檔中使用新組態區段的簡易範例:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="SqlConfigurableRetryLogicConnection"
             type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection, Microsoft.Data.SqlClient"/>
    <section name="SqlConfigurableRetryLogicCommand"
             type="Microsoft.Data.SqlClient.SqlConfigurableRetryCommandSection, Microsoft.Data.SqlClient"/>

    <section name="AppContextSwitchOverrides"
             type="Microsoft.Data.SqlClient.AppContextSwitchOverridesSection, Microsoft.Data.SqlClient"/>
  </configSections>

  <!--Enable safety switch in .NET Core-->
  <AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.EnableRetryLogic=true"/>

  <!--Retry method for SqlConnection-->
  <SqlConfigurableRetryLogicConnection retryMethod ="CreateFixedRetryProvider" numberOfTries ="3" deltaTime ="00:00:10" maxTime ="00:00:30"
                                    transientErrors="40615" />

  <!--Retry method for SqlCommand containing SELECT queries-->
  <SqlConfigurableRetryLogicCommand retryMethod ="CreateIncrementalRetryProvider" numberOfTries ="5" deltaTime ="00:00:10" maxTime ="00:01:10"
                                    authorizedSqlCondition="\b(SELECT)\b" transientErrors="102, 4060, 0"/>
</configuration>

或者,應用程式可以實作自己的 SqlRetryLogicBaseProvider 基底類別提供者,並透過 SqlConnection/SqlCommand 註冊。

事件計數器

下列計數器現在可用於以 .NET Core 3.1+ 和 .NET Standard 2.1+ 為目標的應用程式:

名稱 顯示名稱 Description
active-hard-connections 目前連至伺服器的實際作用中連線 目前對資料庫伺服器開啟的連線數。
hard-connects 伺服器的實際連線速率 每秒對資料庫伺服器開啟的連線數。
hard-disconnects 伺服器的實際中斷連線速率 每秒鐘對資料庫伺服器中斷的連線數。
active-soft-connects 從連線集區擷取的作用中連線 從連線集區取用的已開啟連線數。
soft-connects 從連線集區擷取的連線速率 每秒從連線集區取用的連線數。
soft-disconnects 傳回至連線集區的連線速率 每秒傳回連線集區的連線數。
number-of-non-pooled-connections 未使用連線集區的連線數 尚未列入集區的作用中連線數。
number-of-pooled-connections 連線集區所管理的連線數 管理連接共用基礎結構的現用連接數目。
number-of-active-connection-pool-groups 作用中唯一連接字串數 作用中唯一連接集區群組的數目。 這個計數器是以 AppDomain 中找到的唯一連接字串數目為基礎。
number-of-inactive-connection-pool-groups 等待剪除的唯一連接字串數 標示為清除的唯一連接集區群組的數目。 這個計數器是以 AppDomain 中找到的唯一連接字串數目為基礎。
number-of-active-connection-pools 作用中連線集區數 連接集區的總數。
number-of-inactive-connection-pools 非作用中連線集區數 最近未有任何活動且正等候處置 (Dispose) 的閒置中連接集區數目。
number-of-active-connections 使用中連線的數目 目前使用中的現用連接數目。
number-of-free-connections 連線集區中就緒的連線數 連線集區中可用的開啟連線數。
number-of-stasis-connections 目前等待就緒的連線數 目前正等待動作完成且無法供應用程式使用的連線數。
number-of-reclaimed-connections 來自 GC 的回收連線數 透過記憶體回收作業所回收的連線數,其中 CloseDispose 並非由應用程式呼叫。 注意 未明確關閉或處置連線會影響效能。

這些計數器可以搭配 .NET Core 全域 CLI 工具使用:Windows 或 Linux 中的 dotnet-countersdotnet-trace,以及 Windows 中的 PerfView (提供者名稱需使用 Microsoft.Data.SqlClient.EventSource)。 如需詳細資訊,請參閱擷取事件計數器值

dotnet-counters monitor Microsoft.Data.SqlClient.EventSource -p
PerfView /onlyProviders=*Microsoft.Data.SqlClient.EventSource:EventCounterIntervalSec=1 collect

Azure 身分識別相依性簡介

Microsoft.Data.SqlClient 現在相依於 Azure.Identity 程式庫,以取得「Active Directory 受控識別/MSI」和「Active Directory 服務主體」驗證模式的權杖。 這項變更會對公用介面區產生下列變化:

  • 中斷性變更
    針對「使用者指派的受控識別」,「使用者識別碼」連線屬性現在需要「用戶端識別碼」,而不是「物件識別碼」。
  • 公用 API
    新的唯讀公用屬性:SqlAuthenticationParameters.ConnectionTimeout
  • 相依性
    Azure.Identity v1.3.0

SNI.dll 中的事件追蹤改善項目

Microsoft.Data.SqlClient.SNI (.NET Framework 相依性) 和 Microsoft.Data.SqlClient.SNI.runtime (.NET Core/Standard 相依性) 版本已更新為 v3.0.0-preview1.21104.2。 SNI.dll 中的事件追蹤不再透過用戶端應用程式啟用。 透過 xperfperfview 等工具訂閱 Microsoft.Data.SqlClient.EventSource 提供者的工作階段即足夠。 如需詳細資訊,請參閱原生 SNI 中的事件追蹤支援

啟用資料列版本 Null 行為

SqlDataReader 會傳回 DBNull 值,而不是空的 byte[]。 若要啟用舊版行為,您必須在應用程式啟動時啟用下列 AppContext 切換:「Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior」

Microsoft Entra 預設驗證支援

注意

雖然 Microsoft Entra ID 是 Azure Active Directory(Azure AD)的新名稱,但為了防止破壞現有的環境,Azure AD 仍會保留在某些硬式編碼元素中,例如 UI 字段、連線提供者、錯誤碼和 Cmdlet。 在本文中,這兩個名稱是可交換的。

此 PR 引進新的 SQL 驗證方法 Active Directory Default。 此驗證模式可擴大使用 Microsoft Entra ID 進行使用者驗證的可能性,將登入解決方案延伸至用戶端環境、Visual Studio Code、Visual Studio、Azure CLI 等。

若使用此驗證模式,驅動程式可取得權杖,其方式為從 Azure 身分識別程式庫傳遞「DefaultAzureCredential」來取得存取權杖。 這個模式會嘗試使用這些認證類型,以下列順序取得存取權杖:

  • EnvironmentCredential
    • 使用用戶端搭配祕密或使用者名稱搭配密碼來啟用對 Microsoft Entra ID 的驗證,詳細資料須透過下列環境變數設定:AZURE_TENANT_ID、AZURE_CLIENT_ID、AZURE_CLIENT_SECRET、AZURE_CLIENT_CERTIFICATE_PATH、AZURE_USERNAME、AZURE_PASSWORD (其他詳細資訊)
  • ManagedIdentityCredential
    • 嘗試使用已指派給部署環境的受控識別搭配 Microsoft Entra ID 進行驗證。 「使用者指派的受控識別」的「用戶端識別碼」是從「使用者識別碼」連線屬性中讀取。
  • SharedTokenCacheCredential
    • 使用 Microsoft 應用程式之間共用本機快取中的權杖進行驗證。
  • VisualStudioCredential
    • 使用 Visual Studio 中的資料,啟用對 Microsoft Entra ID 的驗證
  • VisualStudioCodeCredential
    • 使用來自 Visual Studio Code 的資料,啟用對 Microsoft Entra ID 的驗證。
  • AzureCliCredential
    • 使用 Azure CLI 啟用對 Microsoft Entra ID 的驗證,以取得存取權杖。

「Active Directory Default」的驅動程式實作中的 InteractiveBrowserCredential 處於停用狀態,而「Active Directory Interactive」是使用 MFA/互動式驗證取得權杖的唯一選項。*

目前無法使用進一步自訂選項。

自訂主要金鑰存放區提供者註冊增強功能

Microsoft.Data.SqlClient 現在提供更多控制功能,可在應用程式中存取主要金鑰存放區提供者,更妥善支援多租用戶應用程式及其資料行加密/解密機制的使用。 引進下列 API,允許在 SqlConnectionSqlCommand 執行個體上註冊自訂主要金鑰存放區提供者:

public class SqlConnection
{
    public void RegisterColumnEncryptionKeyStoreProvidersOnConnection(IDictionary<string, SqlColumnEncryptionKeyStoreProvider> customProviders)
}
public class SqlCommand 
{
    public void RegisterColumnEncryptionKeyStoreProvidersOnCommand(IDictionary<string, SqlColumnEncryptionKeyStoreProvider> customProviders)
}

SqlConnection 上的靜態 API (SqlConnection.RegisterColumnEncryptionKeyStoreProviders) 用於全域註冊自訂主要金鑰存放區提供者,會繼續受到支援。 全域維護的資料行加密金鑰快取僅適用於全域註冊的提供者。

資料行主要金鑰存放區提供者註冊優先順序

Windows 憑證存放區、CNG Store 和 CSP 可用的內建資料行主要金鑰存放區提供者會進行預先註冊。 如果需要其中一個內建資料行主要金鑰存放區提供者,就不應在連線或命令執行個體上註冊任何提供者。

您可以在三個不同層級向驅動程式註冊自訂主要金鑰存放區提供者。 全域層級會保持原樣。 每個新的連線和命令層級註冊一開始為空的,且可以設定多次。

三個註冊的優先順序如下:

  • 檢查依據命令的註冊是否為空。
  • 如果依據命令的註冊是空的,則檢查依據連線的註冊是否為空。
  • 如果個別連接註冊為空白,系統會檢查全域註冊。

如果在註冊層級找到任何金鑰存放區提供者,驅動程式就不會切換回其他註冊來搜尋提供者。 如果已註冊提供者,但在層級中找不到適當的提供者,則會擲回例外狀況,只包含已檢查註冊中已註冊的提供者。

資料行加密金鑰快取優先順序

若自訂金鑰存放區提供者使用新執行個體層級 API 註冊,則驅動程式不會快取其資料行加密金鑰 (CEK)。 金鑰存放區提供者必須實作自己的快取以提升效能。 若金鑰存放區提供者執行個體是在全域層級的驅動程式中註冊,則驅動程式會停用自訂金鑰存放區提供者所實作資料行加密金鑰的本機快取。

SqlColumnEncryptionKeyStoreProvider 基底類別也引進新的 API,用於設定快取存留時間:

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 位址喜好設定

引進新的連線屬性 IPAddressPreference,用於在建立 TCP 連線時,指定驅動程式的 IP 位址系列喜好設定。 如果 Transparent Network IP Resolution (.NET Framework 中) 或 Multi Subnet Failover 設為 true,則此設定沒有任何作用。 此屬性接受以下三個值:

  • IPv4First

    • 這是預設值。 驅動程式會先使用已解析的 IPv4 位址。 如果都無法成功連線,則會嘗試解析的 IPv6 位址。
  • IPv6First

    • 驅動程式會先使用已解析的 IPv6 位址。 如果都無法成功連線,則會嘗試解析的 IPv4 位址。
  • UsePlatformDefault

    • 驅動程式會依照從 DNS 解析回應收到的順序來嘗試 IP 位址。

3.0 版目標平台支援

  • .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)

Microsoft.Data.SqlClient 2.1 的版本資訊

GitHub 存放庫提供包括相依性在內的完整版本資訊:2.1 版本資訊

2.1 版的新功能

對 Always Encrypted 的跨平台支援

Microsoft.Data.SqlClient v2.1 在下列平台上擴充了對 Always Encrypted 的支援:

支援 Always Encrypted 支援具有安全記憶體保護區的 Always Encrypted 目標 Framework Microsoft.Data.SqlClient 版本 作業系統
.NET Framework 4.6+ 1.1.0+ Windows
.NET Core 2.1+ 2.1.0+1 Windows、Linux、macOS
Yes 2 .NET Standard 2.0 2.1.0+ Windows、Linux、macOS
Yes .NET Standard 2.1+ 2.1.0+ Windows、Linux、macOS

注意

1 在 Microsoft.Data.SqlClient v2.1 版之前,只有 Windows 上支援 Always Encrypted。 2 .NET Standard 2.0 上不支援具有安全記憶體保護區的 Always Encrypted。

Microsoft Entra 裝置程式碼流程驗證

Microsoft.Data.SqlClient v2.1 提供使用 MSAL.NET 進行「裝置程式碼流程」驗證的支援。 參考文件:OAuth 2.0 裝置授權授與流程 \(部分機器翻譯\)

連接字串範例:

Server=<server>.database.windows.net; Authentication=Active Directory Device Code Flow; Database=Northwind;Encrypt=True

下列 API 可讓您自訂裝置程式碼流程回呼機制:

public class ActiveDirectoryAuthenticationProvider
{
    // For .NET Framework, .NET Core and .NET Standard targeted applications
    public void SetDeviceCodeFlowCallback(Func<DeviceCodeResult, Task> deviceCodeFlowCallbackMethod)
}

Microsoft Entra 受控識別驗證

Microsoft.Data.SqlClient v2.1 引進了使用受控識別進行 Microsoft Entra 驗證的支援。

目前支援下列驗證模式關鍵字:

  • Active Directory 受控識別
  • Active Directory MSI (適用於跨 MS SQL 驅動程式相容性)

連接字串範例:

// For System Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory MSI; Encrypt=True; Initial Catalog={db};"

// For System Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory Managed Identity; Initial Catalog={db};"

// For User Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory MSI; Encrypt=True; User Id={ObjectIdOfManagedIdentity}; Initial Catalog={db};"

// For User Assigned Managed Identity
"Server={serverURL}; Authentication=Active Directory Managed Identity; Encrypt=True; User Id={ObjectIdOfManagedIdentity}; Initial Catalog={db};"

Microsoft Entra 互動式驗證增強功能

Microsoft.Data.SqlClient v2.1 新增了下列可自訂「Microsoft Entra 互動式」驗證體驗的 API:

public class ActiveDirectoryAuthenticationProvider
{
    // For .NET Framework targeted applications only
    public void SetIWin32WindowFunc(Func<IWin32Window> iWin32WindowFunc);

    // For .NET Standard targeted applications only
    public void SetParentActivityOrWindowFunc(Func<object> parentActivityOrWindowFunc);

    // For .NET Framework, .NET Core and .NET Standard targeted applications
    public void SetAcquireAuthorizationCodeAsyncCallback(Func<Uri, Uri, CancellationToken, Task<Uri>> acquireAuthorizationCodeAsyncCallback);

    // For .NET Framework, .NET Core and .NET Standard targeted applications
    public void ClearUserTokenCache();
}

SqlClientAuthenticationProviders 設定區段

Microsoft.Data.SqlClient v2.1 引進了新的設定區段 SqlClientAuthenticationProviders (現有 SqlAuthenticationProviders 的複製品)。 定義適當的類型時,仍支援現有的設定區段 SqlAuthenticationProviders,以提供回溯相容性。

新區段讓應用程式組態檔能夠同時包含適用於 System.Data.SqlClient 的 SqlAuthenticationProviders 區段,以及適用於 Microsoft.Data.SqlClient 的 SqlClientAuthenticationProviders 區段。

使用應用程式用戶端識別碼進行 Microsoft Entra 驗證

Microsoft.Data.SqlClient v2.1 引進了將使用者定義的應用程式用戶端識別碼傳遞至 Microsoft 驗證程式庫的支援。 使用 Microsoft Entra ID 進行驗證時,會使用應用程式用戶端識別碼。

已引進下列新的 API:

  1. 在 ActiveDirectoryAuthenticationProvider 中引進新的建構函式:
    [適用於所有 .NET 平台 (.NET Framework、.NET Core 與 .NET Standard)]

    public ActiveDirectoryAuthenticationProvider(string applicationClientId)
    

    Usage :

    string APP_CLIENT_ID = "<GUID>";
    SqlAuthenticationProvider customAuthProvider = new ActiveDirectoryAuthenticationProvider(APP_CLIENT_ID);
    SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, customAuthProvider);
    
    using (SqlConnection sqlConnection = new SqlConnection("<connection_string>")
    {
        sqlConnection.Open();
    }
    
  2. SqlAuthenticationProviderConfigurationSectionSqlClientAuthenticationProviderConfigurationSection 下引進了新的設定屬性:
    [適用於 .NET Framework 與 .NET Core]

    internal class SqlAuthenticationProviderConfigurationSection : ConfigurationSection
    {
        ...
        [ConfigurationProperty("applicationClientId", IsRequired = false)]
        public string ApplicationClientId => this["applicationClientId"] as string;
    }
    
    // Inheritance
    internal class SqlClientAuthenticationProviderConfigurationSection : SqlAuthenticationProviderConfigurationSection
    { ... }
    

    Usage :

    <configuration>
        <configSections>
            <section name="SqlClientAuthenticationProviders"
                             type="Microsoft.Data.SqlClient.SqlClientAuthenticationProviderConfigurationSection, Microsoft.Data.SqlClient" />
        </configSections>
        <SqlClientAuthenticationProviders applicationClientId ="<GUID>" />
    </configuration>
    
    <!--or-->
    
    <configuration>
        <configSections>
            <section name="SqlAuthenticationProviders"
                             type="Microsoft.Data.SqlClient.SqlAuthenticationProviderConfigurationSection, Microsoft.Data.SqlClient" />
        </configSections>
        <SqlAuthenticationProviders applicationClientId ="<GUID>" />
    </configuration>
    

資料分類 v2 支援

Microsoft.Data.SqlClient v2.1.0 引進了對資料分類「敏感度順位」資訊的支援。 現在有下列新的 API 可供使用:

public class SensitivityClassification
{
    public SensitivityRank SensitivityRank;
}

public class SensitivityProperty
{
    public SensitivityRank SensitivityRank;
}

public enum SensitivityRank
{
    NOT_DEFINED = -1,
    NONE = 0,
    LOW = 10,
    MEDIUM = 20,
    HIGH = 30,
    CRITICAL = 40
}

使用中 SqlConnection 的伺服器處理序識別碼

Microsoft.Data.SqlClient v2.1 在使用中的連線上引進了新的 SqlConnection 屬性 (ServerProcessId)。

public class SqlConnection
{
    // Returns the server process Id (SPID) of the active connection.
    public int ServerProcessId;
}

原生 SNI 中的追蹤記錄支援

Microsoft.Data.SqlClient v2.1 擴充了現有的 SqlClientEventSource 實作,以在 SNI.dll 中啟用事件追蹤。 您必須使用 Xperf 之類的工具來擷取事件。

您可以透過將命令傳送至 SqlClientEventSource 來啟用追蹤,如下所示:

// Enables trace events:
EventSource.SendCommand(eventSource, (EventCommand)8192, null);

// Enables flow events:
EventSource.SendCommand(eventSource, (EventCommand)16384, null);

// Enables both trace and flow events:
EventSource.SendCommand(eventSource, (EventCommand)(8192 | 16384), null);

「命令逾時」連接字串屬性

Microsoft.Data.SqlClient v2.1 引進了「命令逾時」連接字串屬性,以覆寫 30 秒的預設值。 您可以使用 SqlCommand 上的 CommandTimeout 屬性來覆寫個別命令的逾時。

連接字串範例:

"Server={serverURL}; Initial Catalog={db}; Encrypt=True; Integrated Security=true; Command Timeout=60"

從原生 SNI 移除符號

在 Microsoft.Data.SqlClient v2.1,我們已從 v2.1.1 \(英文\) 開始,移除了從 Microsoft.Data.SqlClient.SNI.runtime \(英文\) NuGet 的 v2.0.0 \(英文\) 中引進的符號。 現在已將公用符號發佈至 Microsoft 符號伺服器,以供需要存取公用符號的工具 (例如 BinSkim) 使用。

Microsoft.Data.SqlClient 符號的來源連結

從 Microsoft.Data.SqlClient v2.1 開始,Microsoft.Data.SqlClient 符號會與來源連結並發佈至 Microsoft 符號伺服器,以提供增強的偵錯體驗,而不需要下載原始程式碼。

2.1 版目標平台支援

  • .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)

Microsoft.Data.SqlClient 2.0 的版本資訊

GitHub 存放庫提供包括相依性在內的完整版本資訊:2.0 版本資訊

2.0 版的中斷性變更

  • 記憶體保護區提供者介面 SqlColumnEncryptionEnclaveProvider 的存取修飾詞,已從 public 變更為 internal
  • SqlClientMetaDataCollectionNames 類別中的常數已更新,以反映 SQL Server 中的變更。
  • 現在當目標 SQL Server 強制執行 TLS 加密 (此為 Azure 連線的預設值) 時,驅動程式會執行伺服器憑證驗證。
  • SqlDataReader.GetSchemaTable() 現在會傳回空的 DataTable,而不是 null
  • 驅動程式現在會將十進位小數位數四捨五入,以符合 SQL Server 的行為。 如需回溯相容性,可使用 AppContext 參數來啟用先前的截斷行為。
  • 針對使用 Microsoft.Data.SqlClient 的 .NET Framework 應用程式,先前下載至 bin\x64bin\x86 資料夾的 SNI.dll 檔案,現在會命名為 Microsoft.Data.SqlClient.SNI.x64.dllMicrosoft.Data.SqlClient.SNI.x86.dll,並下載至 bin 目錄。
  • SqlConnectionStringBuilder 擷取連接字串以取得一致性時,新的連接字串屬性同義字會取代舊屬性。 閱讀更多資訊

2.0 版的新功能

Microsoft.Data.SqlClient 2.0 引進了下列新功能。

DNS 失敗復原

驅動程式現在會將每個成功連線中 IP 位址快取至支援該功能的 SQL Server 端點。 如果在嘗試連線時 DNS 解析失敗,則驅動程式會嘗試使用該伺服器的快取 IP 位址 (如果有) 來建立連線。

EventSource 追蹤

此版本導入對偵錯工具其擷取事件追蹤記錄的支援。 若要擷取這些事件,用戶端應用程式必須接聽 SqlClient EventSource 實作的事件:

Microsoft.Data.SqlClient.EventSource

如需詳細資訊,請參閱如何在 SqlClient 中啟用事件追蹤

在 Windows 上啟用受控網路

新 AppContext 切換, "Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows" ,可供啟用 Windows 上的受控 SNI 實作,以用於測試與偵錯。 此參數會切換驅動程式的行為,以在 Windows 的 .NET Core 2.1+ 與 .NET Standard 2.0+ 專案中使用受控 SNI,同時消除 Microsoft.Data.SqlClient 程式庫的原生程式庫上所有相依性。

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows", true);

如需驅動程式中可用參數的完整清單,請參閱 SqlClient 中的 AppContext 參數

啟用十進位截斷行為

根據預設,驅動程式會如同 SQL Server,將十進位資料小數位數四捨五入。 如需回溯相容性,則可將 AppCoNtext 參數 "Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal" 設定為 true

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal", true);

全新連接字串屬性同義字

已為下列現有連接字串屬性新增新的同義字,以避免具有一個單字以上的屬性之間的間距混淆。 為支援回溯相容性,仍會繼續支援舊屬性名稱。 但是,從 SqlConnectionStringBuilder 擷取連接字串時,現在會包含新的連接字串屬性。

現有的連接字串屬性 全新同義字
ApplicationIntent 應用程式的意圖
ConnectRetryCount 連線重試計數
ConnectRetryInterval 連線重試間隔
PoolBlockingPeriod 集區封鎖期間
MultipleActiveResultSets Multiple Active Result Set
MultiSubnetFailover 多重子網容錯移轉
TransparentNetworkIPResolution 透明網路 IP 解析
TrustServerCertificate 信任伺服器憑證

SqlBulkCopy RowsCopied 屬性

RowsCopied 屬性提供資料列數目的唯讀存取,該資料列已在進行中的大量複製作業中處理。 此值不一定等於新增至目的地資料表的最終資料列數目。

連線開啟覆寫

可覆寫 SqlConnection.Open () 的預設行為,以停用暫時性錯誤所觸發的 10 秒延遲及自動連線重試。

using SqlConnection sqlConnection = new SqlConnection("Data Source=(local);Integrated Security=true;Initial Catalog=AdventureWorks;");
sqlConnection.Open(SqlConnectionOverrides.OpenWithoutRetry);

注意

請注意,此覆寫只能套用至 SqlConnection.Open(),無法套用至 SqlConnection.OpenAsync()。

支援 Active Directory 互動模式的使用者名稱

使用 .NET Framework 及 .NET Core 的 Microsoft Entra 互動式驗證模式時,可在連接字串中指定使用者名稱

使用使用者識別碼UID 連接字串屬性來設定使用者名稱:

"Server=<server name>; Database=<db name>; Authentication=Active Directory Interactive; User Id=<username>;Encrypt=True;"

SqlBulkCopy 的順序提示

可提供順序提示以改善資料表 (具有叢集索引) 上的大量複製作業效能。 如需詳細資訊,請參閱大量複製作業

SNI 相依性變更

Windows 上的 Microsoft.Data.SqlClient (.NET Core 及 .NET Standard) 現在相依於 Microsoft.Data.SqlClient.SNI.runtime,其取代先前對 runtime.native.System.Data.SqlClient.SNI 的相依性。 全新相依性新增對 ARM 平台的支援,並已支援 Windows 上的 ARM64、x64 與 x86 平台。

2.0 版目標平台支援

  • .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)

Microsoft.Data.SqlClient 1.1.0 的版本資訊

GitHub 存放庫提供包括相依性在內的完整版本資訊:1.1 版本資訊

1.1 版的新功能

具有安全記憶體保護區的 Always Encrypted

Always Encrypted 從 Microsoft SQL Server 2016 開始提供。 安全記憶體保護區從 Microsoft SQL Server 2019 開始提供。 若要使用記憶體保護區功能,則連接字串應該包含必要的證明通訊協定與證明 URL。 例如:

"Attestation Protocol=HGS;Enclave Attestation Url=<attestation_url_for_HGS>"

如需詳細資訊,請參閱

1.1 版目標平台支援

  • .NET Framework 4.6+ (Windows x86、Windows x64)
  • .NET Core 2.1+ (Windows x86、Windows x64、Linux、macOS)
  • .NET Standard 2.0+ (Windows x86、Windows x64、Linux、macOS)

Microsoft.Data.SqlClient 1.0 的版本資訊

除了現有 Microsoft.Data.SqlClient 命名空間的功能,Microsoft.Data.SqlClient 命名空間的初始版本還提供更多功能。

GitHub 存放庫提供包括相依性在內的完整版本資訊:1.0 版本資訊

1.0 版的新功能

超越 .NET Framework 4.7.2 System.Data.SqlClient 的新功能

  • 資料分類:適用於 Azure SQL Database 和 Microsoft SQL Server 2019。

  • UTF-8 支援:適用於 Microsoft SQL Server 2019。

超越 .NET Core 2.2 System.Data.SqlClient 的新功能

  • 資料分類:適用於 Azure SQL Database 和 Microsoft SQL Server 2019。

  • UTF-8 支援:適用於 Microsoft SQL Server 2019。

  • 驗證:Active Directory 密碼驗證模式。

資料分類

當底層來源支援此功能,並包含有關資料敏感度和分類的中繼資料時,資料分類會帶來一組新的 API,公開有關透過 SqlDataReader 擷取之物件的唯讀資料敏感度和分類資訊。 請參閱 SqlClient 中的資料探索及分類的範例應用程式。

public class SqlDataReader
{
    public Microsoft.Data.SqlClient.DataClassification.SensitivityClassification SensitivityClassification
}

namespace Microsoft.Data.SqlClient.DataClassification
{
    public class ColumnSensitivity
    {
        public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.SensitivityProperty> SensitivityProperties
    }
    public class InformationType
    {
        public string Id
        public string Name
    }
    public class Label
    {
        public string Id
        public string Name
    }
    public class SensitivityClassification
    {
        public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.ColumnSensitivity> ColumnSensitivities
        public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.InformationType> InformationTypes
        public System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.Data.SqlClient.DataClassification.Label> Labels
    }
    public class SensitivityProperty
    {
        public Microsoft.Data.SqlClient.DataClassification.InformationType InformationType
        public Microsoft.Data.SqlClient.DataClassification.Label Label
    }
}

UTF-8 支援

UTF-8 支援不需要進行任何應用程式程式碼變更。 這些 SqlClient 變更會在伺服器支援 UTF-8 且底層資料行定序為 UTF-8 時,將用戶端與伺服器之間的通訊最佳化。 請參閱 SQL Server 2019 的新功能下方的 UTF-8 一節。

具有安全記憶體保護區的 Always Encrypted

一般來說,在 .NET Framework 及內建資料行主要金鑰存放區提供者上使用 System.Data.SqlClient 的現有文件,現在也應該使用 .NET Core。

搭配使用 Always Encrypted 與 .NET Framework Data Provider 進行開發

Always Encrypted:保護敏感性資料並將加密金鑰儲存在 Windows 憑證存放區中 \(部分機器翻譯\)

驗證

您可以使用 Authentication 連接字串選項來指定不同的驗證模式。 如需詳細資訊,請參閱 SqlAuthenticationMethod 的文件 \(部分機器翻譯\)。

注意

自訂金鑰存放區提供者 (例如 Azure Key Vault 提供者) 將需要更新,才能支援 Microsoft.Data.SqlClient。 同樣地,記憶體保護區提供者也必須更新,才能支援 Microsoft.Data.SqlClient。 僅針對 .NET Framework 和 .NET Core 目標支援 Always Encrypted。 並未針對 .NET Standard 提供支援,因為 .NET Standard 遺漏了某些加密相依性。

1.0 版目標平台支援

  • .NET Framework 4.6+ (Windows x86、Windows x64)
  • .NET Core 2.1+ (Windows x86、Windows x64、Linux、macOS)
  • .NET Standard 2.0+ (Windows x86、Windows x64、Linux、macOS)