.NET と Microsoft.Data.SqlClient ライブラリを使って Azure SQL Database に接続し、クエリを実行する

適用対象: Azure SQL Database

このクイックスタートでは、.NET と Microsoft.Data.SqlClient ライブラリを使って Azure SQL Database 内のデータベースにアプリケーションを接続し、クエリを実行する方法について説明します。 このクイックスタートでは、データベースに接続するための推奨されるパスワードレス アプローチに従います。 パスワードレス接続について詳しくは、パスワードレス ハブに関する記事を参照してください。

前提条件

データベースを構成する

Azure SQL Database への安全なパスワードレス接続には、特定のデータベース構成が必要です。 Azure の論理サーバーで次の設定を確認し、ローカル環境とホスト環境の両方で Azure SQL Database に適切に接続します。

  1. ローカル開発の接続の場合は、ローカル コンピューターの IP アドレスやその他の Azure サービスで接続できるように論理サーバーが構成されていることを確認します。

    • お使いのサーバーの [ネットワーク] ページに移動します。

    • [選択されたネットワーク] ラジオ ボタンを切り替えて、追加の構成オプションを表示します。

    • [Add your client IPv4 address(xx.xx.xx.xx)] (クライアント IPv4 アドレスの追加 (xx.xx.xx.xx)) を選び、ローカル コンピューターの IPv4 アドレスからの接続を有効にするファイアウォール規則を追加します。 または、[+ Add a firewall rule] (ファイアウォール規則の追加) を選び、選んだ特定の IP アドレスを入力することもできます。

    • [Azure サービスおよびリソースにこのサーバーへのアクセスを許可する] チェックボックスがオンになっていることを確認します。

      ファイアウォール規則を構成する方法を示すスクリーンショット。

      警告

      [Azure サービスおよびリソースにこのサーバーへのアクセスを許可する] 設定を有効にすることは、運用環境のシナリオでは推奨されるセキュリティ プラクティスではありません。 実際のアプリケーションでは、より強力なファイアウォール制限や仮想ネットワーク構成など、より安全なアプローチを実装する必要があります。

      データベース セキュリティの構成について詳しくは、次のリソースを参照してください。

  2. また、サーバーでは Microsoft Entra 認証が有効になっており、Microsoft Entra 管理者アカウントが割り当てられている必要があります。 ローカル開発接続の場合、Microsoft Entra 管理者アカウントは、ローカルで Visual Studio または Azure CLI にログインできるアカウントである必要があります。 論理サーバーの Microsoft Entra ID ページで、サーバーで Microsoft Entra 認証が有効になっているかどうかを確認できます。

    Microsoft Entra 認証を有効にする方法を示すスクリーンショット。

  3. 個人の Azure アカウントを使用している場合は、アカウントをサーバー管理者として割り当てるために、Microsoft Entra がセットアップされ、Azure SQL Database 用に構成されていることを確認してください。企業アカウントを使用している場合は、Microsoft Entra ID がおそらくすでに構成済みになっています。

プロジェクトを作成する

次の手順では、.NET CLI または Visual Studio 2022 のいずれかを使って、.NET の最小限の Web API を作成します。

  1. Visual Studio のメニューで、[ファイル]>[新規]>[プロジェクト..] の順に移動します。

  2. ダイアログ ウィンドウで、プロジェクト テンプレートの検索ボックスに「ASP.NET」と入力し、ASP.NET Core Web API の結果を選択します。 ダイアログの下部にある [次へ] を選択します。

  3. [プロジェクト名] に「DotNetSQL」と入力します。 残りのフィールドは既定値のままにし、[次へ] を選択します。

  4. [フレームワーク] では、[.NET 7.0] を選択し、[コントローラーを使用する (最小限の API を使用する場合はオフにします)] をオフにします。 このクイックスタートでは、最小限の API テンプレートを使用して、エンドポイントの作成と構成を合理化します。

  5. [作成] を選択します。 新しいプロジェクトが Visual Studio 環境内で開きます。

Microsoft.Data.SqlClient ライブラリを追加する

.NET を使って Azure SQL Database に接続するには、Microsoft.Data.SqlClient をインストールします。 このパッケージは、データベースへの接続、コマンドの実行、結果の取得を行うためのデータ プロバイダーとして機能します。

Note

必ず System.Data.SqlClient ではなく Microsoft.Data.SqlClient をインストールしてください。 Microsoft.Data.SqlClient は SQL クライアント ライブラリの新しいバージョンであり、追加機能が提供されています。

  1. [ソリューション エクスプローラー] ウィンドウで、プロジェクトの [依存関係] ノードを右クリックし、[NuGet パッケージの管理] を選択します。

  2. 表示されたウィンドウで、「SqlClient」を検索します。 Microsoft.Data.SqlClient の結果を見つけて、[インストール] を選択します。

接続文字列の構成

Azure SQL Database へのパスワードレス接続を使用したローカル開発の場合は、次の ConnectionStrings セクションを appsettings.json ファイルに追加します。 プレースホルダー <database-server-name><database-name> を実際の値に置き換えます。

"ConnectionStrings": {
    "AZURE_SQL_CONNECTIONSTRING": "Server=tcp:<database-server-name>.database.windows.net,1433;Initial Catalog=<database-name>;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Authentication=\"Active Directory Default\";"
}

パスワードレスの接続文字列では Authentication="Active Directory Default" の構成値を設定します。これにより、DefaultAzureCredential というクラスを使用して Azure SQL Database に接続するように Microsoft.Data.SqlClient ライブラリに指示されます。 DefaultAzureCredential は、Azure サービスへのパスワードレス接続を可能にし、SQL クライアント ライブラリが依存する Azure ID ライブラリによって提供されます。 DefaultAzureCredential では複数の認証方法がサポートされており、さまざまな環境で実行時にどれを使うかが決定されます。

たとえば、アプリがローカルで実行されている場合、DefaultAzureCredential では、Visual Studio へのサインインに使用しているユーザー、または Azure CLI などの他のローカル ツールで認証を行います。 アプリが Azure にデプロイされると、同じコードで、ホストされるアプリに関連付けられているマネージド ID が検出され、適用されます。これは後で構成します。 Azure ID ライブラリの概要に関する記事では、DefaultAzureCredential が資格情報を検索する順序と場所について説明されています。

注意

パスワードレスの接続文字列は、ソース管理にコミットしても安全です。ユーザー名、パスワード、アクセス キーなどのシークレットが含まれていないためです。

Azure SQL Database に接続するコードを追加する

Program.cs ファイルの内容を、以下の重要な手順を行う次のコードに置き換えます。

  • appsettings.json からパスワードレスの接続文字列を取得する
  • 起動時にデータベース内に Persons テーブルを作成する (テスト シナリオのみ)
  • Persons テーブルに格納されているすべてのレコードを取得する HTTP GET エンドポイントを作成します
  • Persons テーブルに新しいレコードを追加する HTTP POST エンドポイントを作成します
using Microsoft.Data.SqlClient;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// For production scenarios, consider keeping Swagger configurations behind the environment check
// if (app.Environment.IsDevelopment())
// {
    app.UseSwagger();
    app.UseSwaggerUI();
// }

app.UseHttpsRedirection();

string connectionString = app.Configuration.GetConnectionString("AZURE_SQL_CONNECTIONSTRING")!;

try
{
    // Table would be created ahead of time in production
    using var conn = new SqlConnection(connectionString);
    conn.Open();

    var command = new SqlCommand(
        "CREATE TABLE Persons (ID int NOT NULL PRIMARY KEY IDENTITY, FirstName varchar(255), LastName varchar(255));",
        conn);
    using SqlDataReader reader = command.ExecuteReader();
}
catch (Exception e)
{
    // Table may already exist
    Console.WriteLine(e.Message);
}

app.MapGet("/Person", () => {
    var rows = new List<string>();

    using var conn = new SqlConnection(connectionString);
    conn.Open();

    var command = new SqlCommand("SELECT * FROM Persons", conn);
    using SqlDataReader reader = command.ExecuteReader();

    if (reader.HasRows)
    {
        while (reader.Read())
        {
            rows.Add($"{reader.GetInt32(0)}, {reader.GetString(1)}, {reader.GetString(2)}");
        }
    }

    return rows;
})
.WithName("GetPersons")
.WithOpenApi();

app.MapPost("/Person", (Person person) => {
    using var conn = new SqlConnection(connectionString);
    conn.Open();

    var command = new SqlCommand(
        "INSERT INTO Persons (firstName, lastName) VALUES (@firstName, @lastName)",
        conn);

    command.Parameters.Clear();
    command.Parameters.AddWithValue("@firstName", person.FirstName);
    command.Parameters.AddWithValue("@lastName", person.LastName);

    using SqlDataReader reader = command.ExecuteReader();
})
.WithName("CreatePerson")
.WithOpenApi();

app.Run();

最後に、Person クラスを Program.cs ファイルの下部に追加します。 このクラスは、データベースの Persons テーブル内の 1 つのレコードを表します。

public class Person
{
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
}

アプリをローカルで実行してテストする

アプリをローカルでテストする準備ができました。 データベースの管理者として設定したのと同じアカウントを使って、Visual Studio または Azure CLI にサインインしていることを確認します。

  1. Visual Studio の上部にある実行ボタンを押して、API プロジェクトを起動します。

  2. Swagger UI ページで、POST メソッドを展開し、[テスト] を選択します。

  3. 姓と名の値を含むようにサンプル JSON を変更します。 [実行] を選択して、新しいレコードをデータベースに追加します。 API は正常な応答を返します。

    API をテストする方法を示すスクリーンショット。

  4. Swagger UI ページで GET メソッドを展開し、[テスト] を選択します。 [実行] を選択すると、先ほど作成した人物が返されます。

Azure App Service にデプロイする

アプリを Azure にデプロイする準備ができました。 Visual Studio によって、1 つのワークフローで Azure アプリ サービスを作成し、アプリケーションをデプロイできます。

  1. アプリが停止していることと、正常にビルドされていることを確認します。

  2. Visual Studio の [ソリューション エクスプローラー] ウィンドウで、最上位レベルのプロジェクト ノードを右クリックし、[発行] を選択します。

  3. 発行ダイアログで、デプロイ ターゲットとして [Azure] を選んでから、[次へ] を選択します。

  4. 具体的なターゲットとしては、[Azure App Service (Windows)] を選択し、[次へ] を選択します。

  5. [+] アイコンを選択して、デプロイ先となる新しい App Service を作成し、次の値を入力します。

    • 名前: 既定値のままにします。

    • サブスクリプション名: デプロイするサブスクリプションを選択します。

    • [リソース グループ]: [新規] を選択し、msdocs-dotnet-sql という名前の新しいリソース グループを作成します。

    • [ホスティング プラン]: [新規] を選択して、ホスティング プラン ダイアログを開きます。 既定値のままにして [OK] を選択します。

    • [作成] 選択して、元のダイアログを閉じます。 Visual Studio によって、Azure に App Service リソースが作成されます。

      Visual Studio を使用してデプロイする方法を示すスクリーンショット。

  6. リソースが作成されたら、それがアプリ サービスの一覧で選択されていることを確認してから、[次へ] を選択します。

  7. [API Management] の手順で、下部にある [この手順をスキップする] チェックボックスをオンにし、[完了] を選択します。

  8. [終了] 手順で、ダイアログが自動的に閉じない場合は [閉じる] を選択します。

  9. 発行プロファイルの概要の右上にある [発行] を選択して、アプリを Azure にデプロイします。

デプロイが完了すると、Visual Studio によってブラウザーが起動され、ホストされているアプリが表示されますが、この時点ではアプリは Azure で正しく動作しません。 データを取得するために、App Service と SQL データベースの間にセキュリティで保護された接続を構成する必要があります。

App Service を Azure SQL Database に接続する

App Service インスタンスと Azure SQL Database の間にパスワードレス接続を作成するには、次の手順が必要です。

  1. App Service 用のマネージド ID を作成します。 アプリに含まれている Microsoft.Data.SqlClient ライブラリによって、マネージド ID が自動的に検出されます。ローカルの Visual Studio ユーザーが検出されたときと同様です。
  2. SQL データベース ユーザーを作成し、App Service のマネージド ID に関連付けます。
  3. 読み取り、書き込み、場合によってはその他のアクセス許可を付与する SQL ロールをデータベース ユーザーに割り当てます。

これらの手順を実施するために使用できるツールは複数あります。

Service Connector は、Azure のさまざまなサービス間の認証された接続を合理化するツールです。 現在、Service Connector では、Azure CLI 経由で az webapp connection create sql コマンドを使って、App Service を SQL データベースに接続することがサポートされています。 この 1 つのコマンドによって、上記の 3 つの手順が完了します。

az webapp connection create sql \
    -g <app-service-resource-group> \
    -n <app-service-name> \
    --tg <database-server-resource-group> \
    --server <database-server-name> \
    --database <database-name> \
    --system-identity

Service Connector によって行われた変更は、App Service の設定で確認できます。

  1. App Service の [ID] ページに移動します。 [システム割り当て済み] タブで、[状態][オン] に設定されているはずです。 この値は、システム割り当てマネージド ID がアプリに対して有効になっていたことを意味します。

  2. App Service リソースの [構成] ページに移動します。 [接続文字列] タブに、AZURE_SQL_CONNECTIONSTRING という名前の接続文字列が表示されているはずです。 [Click to show value] (クリックして値を表示にする) のテキストを選択すると、生成されたパスワードレスの接続文字列が表示されます。 この接続文字列の名前は、アプリで構成したものと一致するため、Azure で実行すると自動的に検出されます。

重要

このソリューションでは簡単な方法で開始できますが、これは運用レベル環境のベスト プラクティスではありません。 それらのシナリオでは、アプリで 1 つの昇格された ID を使用して、すべての操作を実行すべきではありません。 特定のタスクのための特定のアクセス許可を持つ複数の ID を構成することで、最小限の特権の原則を実装できるようにする必要があります。

データベース ロールとセキュリティの構成について詳しくは、次のリソースを参照してください。

デプロイされたアプリケーションをテストする

  1. App Service の [概要] ページの上部にある [参照] ボタンを選択して、アプリのルート URL を起動します。

  2. URL に /swagger/index.html パスを追加して、ローカルで使用したのと同じ Swagger テスト ページを読み込みます。

  3. GET および POST 要求のテストを実行して、エンドポイントが期待どおりに動作することを確認します。

ヒント

テスト中に 500 内部サーバー エラーが発生した場合は、データベース ネットワーク構成が原因である可能性があります。 論理サーバーが、「データベースを構成する」セクションで概説されている設定で構成されていることを確認します。

おめでとうございます。 これで、ローカル環境とホスト環境の両方で、アプリケーションを Azure SQL Database に接続することができました。

リソースのクリーンアップ

Azure SQL Database の操作が完了したら、意図しないコストを回避するためにリソースを削除します。

  1. Azure portal の検索バーで「Azure SQL」を検索し、一致する結果を選択します。

  2. データベースの一覧でデータベースを見つけて選択します。

  3. Azure SQL Database の [概要] ページで、[削除] を選択します。

  4. 開かれる [削除しますか...] ページで、データベースの名前を入力して確認し、[削除] を選択します。