在這個快速入門中,你會建立一個 .NET 主控台應用程式:
- 它會從環境變數讀取連線字串,而非從原始碼中讀取。
- 非同步開啟連線。
- 如果表格不存在,則建立該表格。
- 插入一列帶有參數化指令的列。
- 使用參數化查詢讀取資料列。
- 處理 SQL 與取消錯誤。
範例中使用了 Microsoft。Data.SqlClient 7.0.3,目前的穩定版本。
Prerequisites
你需要 .NET 10 SDK 或後續支援的 .NET SDK。
建立 SQL 資料庫
在以下平台建立或連接 SQL 資料庫:
快速入門會自行建立資料表,因此不需要範例資料。 資料庫識別需要具備連線,以及建立資料表、向資料表插入資料,並從資料表選取資料的權限。
在 Microsoft Fabric 的 SQL 資料庫中,從 SQL 資料庫項目複製伺服器名稱與資料庫名稱。 不要使用 SQL Analytics 端點。 該身分需要項目的讀取權限,而工作區角色或項目權限可提供此權限。 欲了解更多資訊,請參閱 SQL 資料庫中的認證。 不支援 SQL 認證。
對於 Azure SQL Database,請設定 Microsoft Entra ID 認證與資料庫存取。
建立專案
執行以下命令:
dotnet new console --framework net10.0 --name SqlClientQuickstart
cd SqlClientQuickstart
dotnet add package Microsoft.Data.SqlClient --version 7.0.3
dotnet add package Microsoft.Data.SqlClient.Extensions.Azure --version 7.0.3
擴充套件提供驅動程式提供的 Microsoft Entra ID 認證模式。 僅使用 Windows 整合認證或 SQL 認證的應用程式可以省略 Microsoft.Data.SqlClient.Extensions.Azure。
設定連線
設定 SQL_CONNECTION_STRING 資料庫的環境變數。 不要在原始碼中放入密碼、存取權杖或正式環境的連線字串。
選擇其中一個起始點並替換佔位符。
Fabric SQL 或 Azure SQL 搭配無密碼驗證
請以 Microsoft Entra ID 中有資料庫存取權的身份登入。 本地開發時,請使用開發工具如 Azure CLI:
az login
從 Fabric 或 Azure SQL 資料庫中複製精確的伺服器和資料庫名稱。 對於 PowerShell:
$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'
針對 Bash:
export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'
對於一個在 Azure 中託管且連接 Azure SQL 的應用程式,請授予其管理身份資料庫存取權,然後使用 Authentication=Active Directory Managed Identity。 關於其他 Microsoft Entra ID 選項,請參見 Microsoft Entra ID 認證。
透過 TCP 的 SQL Server
使用伺服器、埠號、資料庫,並從你現有的 SQL Server 或你遵循的設定指南登入。 以下的 SQL 驗證範例是針對本地開發容器。 對於 PowerShell:
$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;User ID=<user_id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'
針對 Bash:
export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;User ID=<user_id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'
Caution
TrustServerCertificate=true 跳過伺服器憑證驗證。 只用在沒有受信任憑證的本地開發實例上。 對於共享或生產型 SQL Server 實例,安裝一個客戶端信任的憑證,使用該憑證上的伺服器名稱,然後移除 TrustServerCertificate=true。
若環境支援 Windows 整合認證或 Kerberos,則將 和 Password 替換User ID為 Integrated Security=true。 關於設定需求,請參見 SQL Server 認證。
新增應用程式代碼
請將 Program.cs 的內容替換為以下代碼:
using System.Data;
using Microsoft.Data.SqlClient;
string? connectionString =
Environment.GetEnvironmentVariable("SQL_CONNECTION_STRING");
if (string.IsNullOrWhiteSpace(connectionString))
{
Console.Error.WriteLine(
"Set the SQL_CONNECTION_STRING environment variable.");
return 1;
}
using var cancellation = new CancellationTokenSource();
Console.CancelKeyPress += (_, eventArgs) =>
{
eventArgs.Cancel = true;
cancellation.Cancel();
};
try
{
await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync(cancellation.Token);
const string createTableSql = """
IF OBJECT_ID(N'dbo.SqlClientQuickstart', N'U') IS NULL
BEGIN
CREATE TABLE dbo.SqlClientQuickstart
(
Id int IDENTITY(1, 1) PRIMARY KEY,
Message nvarchar(200) NOT NULL,
CreatedAt datetimeoffset NOT NULL
CONSTRAINT DF_SqlClientQuickstart_CreatedAt
DEFAULT sysdatetimeoffset()
);
END;
""";
using (var createCommand =
new SqlCommand(createTableSql, connection) { CommandTimeout = 30 })
{
await createCommand.ExecuteNonQueryAsync(cancellation.Token);
}
const string insertSql = """
INSERT INTO dbo.SqlClientQuickstart (Message)
OUTPUT INSERTED.Id
VALUES (@message);
""";
int insertedId;
using (var insertCommand =
new SqlCommand(insertSql, connection) { CommandTimeout = 30 })
{
insertCommand.Parameters.Add(
new SqlParameter("@message", SqlDbType.NVarChar, 200)
{
Value = "Hello from Microsoft.Data.SqlClient"
});
object? result =
await insertCommand.ExecuteScalarAsync(cancellation.Token);
insertedId = Convert.ToInt32(result);
}
const string querySql = """
SELECT Id, Message, CreatedAt
FROM dbo.SqlClientQuickstart
WHERE Id = @id
ORDER BY Id;
""";
using var queryCommand =
new SqlCommand(querySql, connection) { CommandTimeout = 30 };
queryCommand.Parameters.Add(
new SqlParameter("@id", SqlDbType.Int) { Value = insertedId });
await using SqlDataReader reader =
await queryCommand.ExecuteReaderAsync(cancellation.Token);
while (await reader.ReadAsync(cancellation.Token))
{
Console.WriteLine(
$"{reader.GetInt32(0)}: {reader.GetString(1)} " +
$"at {reader.GetDateTimeOffset(2):O}");
}
return 0;
}
catch (OperationCanceledException)
{
Console.Error.WriteLine("The operation was canceled.");
return 2;
}
catch (SqlException ex)
{
Console.Error.WriteLine(
$"SQL error {ex.Number}, connection {ex.ClientConnectionId}: " +
ex.Message);
return 3;
}
參數類型與大小與資料表欄位相符。 參數會與 SQL 文字分開傳送值,防止這些值改變命令語法,並幫助 SQL Server 重用查詢計畫。
await using 即使發生例外狀況,也會釋放讀取器和連線。 釋放連線會將其實體連線歸還至連線集區,而不是讓一個連線在應用程式的整個生命週期內維持開啟狀態。
執行應用程式
執行應用程式:
dotnet run
應用程式會列印它插入的那一列:
1: Hello from Microsoft.Data.SqlClient at <timestamp>
每個資料庫的身份值與時間戳記各不相同。
如果連線失敗,則使用 SQL 錯誤號碼和錯誤輸出中的用戶端連線 ID。 檢查伺服器和資料庫名稱、網路存取、資料庫權限、認證設定和憑證設定。 不要將 TrustServerCertificate=true 新增至 Azure SQL 或生產環境連線,作為通用的連線修正方式。
在應用程式中使用該圖案
當你將範例移入 API、服務、桌面應用程式或背景工作器時,請遵守以下界限:
- 透過應用程式的設定系統載入連接資訊。
- 開啟一個連線來執行短暫的工作單元,然後將其釋放。
- 在 open、command 和 reader 呼叫中傳遞
CancellationToken。 - 根據作業設定命令逾時時間。
- 對於每個從 SQL 陳述式外部傳入的值,都應使用參數。
- 記錄
SqlException.Number和ClientConnectionId,但不要記錄認證資訊或存取權杖。 - 僅在發生暫態故障時才加入重試機制,且僅在可安全重複執行該作業時才這麼做。