.NET アプリで Microsoft.Data.SqlClient を使用する

このクイックスタートでは、以下の内容の.NETコンソールアプリケーションを作成します。

  • ソースコードではなく環境から接続文字列を読み取る。
  • 非同期で接続を開きます。
  • テーブルが存在しない場合は作成します。
  • パラメータ化されたコマンドで行を挿入します。
  • パラメータ化されたクエリで行を読み込みます。
  • SQLやキャンセルエラーを処理します。

例ではMicrosoftを使用しています。Data.SqlClient 7.0.3、現在の安定版リリースです。

前提条件

.NET 10 SDKか、それ以降対応する.NET SDKが必要です。

SQL データベースを作成する

以下のいずれかのプラットフォームでSQLデータベースを作成または接続してください:

クイックスタートは独自のテーブルを作成するため、サンプルデータは不要です。 データベースのアイデンティティは接続やテーブルの作成、挿入、選択の許可が必要です。

Microsoft FabricのSQLデータベースでは、SQLデータベースの項目からサーバー名とデータベース名をコピーします。 SQLアナリティクスエンドポイントは使わないでください。 アイデンティティには「アイテムを読み込み」権限が必要で、ワークスペースロールやアイテム権限で提供できます。 詳細については、 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認証モードを提供します。 統合認証やSQL認証のみを使用するアプリケーションWindowsMicrosoft.Data.SqlClient.Extensions.Azure省略できます。

接続の設定

データベースの SQL_CONNECTION_STRING 環境変数を設定してください。 ソースコードにパスワード、アクセストークン、または本番環境の接続文字列を入れないでください。

これらの開始点から1つを選び、プレースホルダーを置き換えてください。

パスワードレス認証を使用した Fabric SQL または Azure SQL

データベースにアクセスできるMicrosoft Entra IDのIDでサインインしてください。 ローカル開発の場合は、Azure CLIのような開発者ツールをご利用ください。

az login

FabricやAzure SQLデータベースの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に接続するアプリケーションに対しては、管理IDデータベースへのアクセスを許可し、その後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を削除してください。

環境が統合認証やKerberosに対応しWindowsなら、User IDPasswordIntegrated 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 例外が発生した場合でも、リーダーと接続を破棄します。 接続を破棄することで、アプリケーションの存続期間中1つの接続を開いたままにするのではなく、物理的な接続を接続プールに戻します。

アプリケーションを実行する

アプリケーションを実行します。

dotnet run

アプリケーションは挿入した行を印刷します:

1: Hello from Microsoft.Data.SqlClient at <timestamp>

識別値とタイムスタンプは各データベースで異なります。

接続が失敗した場合は、エラー出力のSQLエラー番号とクライアント接続IDを使用します。 サーバー名やデータベース名、ネットワークアクセス、データベース権限、認証設定、証明書設定を確認してください。 一般的な接続修正としてAzure SQLや本番環境の接続にTrustServerCertificate=trueを追加しないでください。

アプリケーションでパターンを使う

サンプルをAPI、サービス、デスクトップアプリケーション、またはバックグラウンドワーカーに移行する際には、以下の境界線を守りましょう:

  • アプリケーションの設定システムを通じて接続情報を読み込みます。
  • 短い作業単位のために 1 つの接続を開き、終わったら破棄します。
  • CancellationTokenをオープンコール、コマンドコール、リーダーコールに通します。
  • 操作に応じてコマンドのタイムアウトを設定してください。
  • SQL文の外部から来るすべての値にパラメータを使いましょう。
  • SqlException.NumberClientConnectionId を記録し、ログイン情報やアクセストークンはログに記録しないでください。
  • 再試行は一時的な故障のみ、かつ操作が安全に再現できる場合にのみ追加します。

次のステップ