次の方法で共有


.NET.NET Aspire を使用してデータベース内のデータをシード処理する

この記事では、アプリの起動時にデータベースにデータをシードするように .NET.NET Aspire プロジェクトを構成する方法について説明します。 .NET Aspireを使用すると、Entity Framework Core、EF Core、SQL Serverなどの一般的なプラットフォームのデータベース スクリプトまたはPostgreSQL (MySQL) を使用してデータをシードできます。

データをシード処理するタイミング

データをシード処理すると、データベース テーブルにデータ行が事前に設定されるため、アプリをテストする準備が整います。 次のシナリオでデータをシードすることができます。

  • 製品カタログや顧客の一覧など、意味のある一連のデータに対して、アプリのさまざまな機能を手動で開発してテストする必要があります。
  • テスト スイートを実行して、特定のデータ セットで機能が正しく動作することを確認する必要があります。

データを手動でシード処理するのは面倒で時間がかかるため、可能な限りプロセスを自動化する必要があります。 データベースのシード処理は、起動時に .NET Aspire プロジェクトのデータベース スクリプトを実行するか、 EF Coreなどのツールを使用して実行することで、基になる多くの問題を処理します。

コンテナー化されたデータベースについて

既定では、.NET.NET Aspire データベース統合はコンテナー化されたデータベースに依存するため、データをシード処理しようとすると次の課題が発生します。

  • 既定では、 .NET.NET Aspire は、アプリが再起動されるたびにコンテナーを破棄して再作成します。つまり、実行するたびにデータベースを再シードする必要があります。
  • 選択したデータベース テクノロジによっては、新しいコンテナー インスタンスで既定のデータベースが作成される場合と作成されない場合があります。つまり、データベース自体を作成する必要がある場合もあります。
  • 既定のデータベースが存在する場合でも、ほとんどの場合、特定のアプリに必要な名前やスキーマはありません。

.NET.NET Aspire では、ボリューム、バインド マウント、およびいくつかの構成を使用してこれらの課題を解決して、データを効果的にシードできます。

ヒント

DockerやPodmanなどのコンテナー ホストは、ボリュームとバインド マウントをサポートします。両方とも、コンテナーの再起動時に保持されるデータの場所を提供します。 ボリュームは、パフォーマンス、移植性、およびセキュリティが向上するため、推奨されるソリューションです。 コンテナー ホストはボリュームを作成し、引き続き制御します。 各ボリュームには、複数のコンテナーのデータを格納できます。 バインド マウントの機能は比較的限られていますが、ホスト コンピューターからデータにアクセスできます。

手記

データベース コンテナー サンプル アプリの にアクセスして、各データベース オプションの完全なプロジェクトとファイル構造を表示します。

SQL スクリプトを使用してデータをシード処理する

データベース シード処理スクリプトを実行するための推奨される方法は、使用するデータベース サーバーによって異なります。

.NET.NET Aspire 9.2 以降では、WithCreationScript メソッドを使用して、データベースの作成時に T-SQL スクリプトを確実に実行できます。 データベース、必要なテーブル、およびその他のデータベース オブジェクトを作成して設定する SQL コードをこのスクリプトに追加します。

次のコードは、アドレス帳データベースを作成して設定する T-SQL スクリプトの例です。

-- SQL Server init script

-- Create the AddressBook database
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = N'AddressBook')
BEGIN
  CREATE DATABASE AddressBook;
END;
GO

USE AddressBook;
GO

-- Create the Contacts table
IF OBJECT_ID(N'Contacts', N'U') IS NULL
BEGIN
    CREATE TABLE Contacts
    (
        Id        INT PRIMARY KEY IDENTITY(1,1) ,
        FirstName VARCHAR(255) NOT NULL,
        LastName  VARCHAR(255) NOT NULL,
        Email     VARCHAR(255) NULL,
        Phone     VARCHAR(255) NULL
    );
END;
GO

-- Ensure that either the Email or Phone column is populated
IF OBJECT_ID(N'chk_Contacts_Email_Phone', N'C') IS NULL
BEGIN
    ALTER TABLE Contacts
    ADD CONSTRAINT chk_Contacts_Email_Phone CHECK
    (
        Email IS NOT NULL OR Phone IS NOT NULL
    );
END;
GO

-- Insert some sample data into the Contacts table
IF (SELECT COUNT(*) FROM Contacts) = 0
BEGIN
    INSERT INTO Contacts (FirstName, LastName, Email, Phone)
    VALUES
        ('John', 'Doe', 'john.doe@example.com', '555-123-4567'),
        ('Jane', 'Doe', 'jane.doe@example.com', '555-234-5678');
END;
GO

.NET.NET Aspireが実行できるように、このスクリプトがアプリ ホストの出力ディレクトリにコピーされていることを確認する必要があります。 次の XML を .csproj ファイルに追加します。

<ItemGroup>
  <None Include="..\DatabaseContainers.ApiService\data\sqlserver\init.sql" Link="init.sql">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

Include パラメーターを、プロジェクト内の SQL スクリプトへのパスと一致するように調整します。

次に、アプリ ホストの AppHost.cs (または Program.cs) ファイルで、データベースを作成し、作成スクリプトを実行します。

var sqlserver = builder.AddSqlServer("sqlserver")
    // Configure the container to store data in a volume so that it persists across instances.
    .WithDataVolume()
    // Keep the container running between app host sessions.
    .WithLifetime(ContainerLifetime.Persistent);

// Add the database to the application model so that it can be referenced by other resources.
var initScriptPath = Path.Join(Path.GetDirectoryName(typeof(Program).Assembly.Location), "init.sql");
var addressBookDb = sqlserver.AddDatabase("AddressBook")
    .WithCreationScript(File.ReadAllText(initScriptPath));

前述のコード:

  • SQL Serverを呼び出して、builder.AddSqlServer() コンテナーを作成します。
  • WithDataVolume()WithLifetime(ContainerLifetime.Persistent)を呼び出すことによって、デバッグ セッション間でデータが保持されるようにします。
  • 出力フォルダー内の T-SQL スクリプトへのパスを取得します。
  • WithCreationScript()を呼び出して、データベースを作成してシード処理します。

EF Core を使用してデータをシード処理する

また、起動時に明示的に移行を実行することで、.NET Aspire を使用して EF Core プロジェクトのデータをシードすることもできます。 EF Core は、基になるデータベース接続とスキーマの作成を自動的に処理するため、コンテナーの起動時にボリュームを使用したり、SQL スクリプトを実行したりする必要がなくなります。

重要

これらの種類の構成は開発中にのみ行う必要があるため、現在の環境コンテキストをチェックする条件付きを必ず追加してください。

Program.cs プロジェクトの ファイルに次のコードを追加します。

// Register DbContext class
builder.AddSqlServerDbContext<TicketContext>("sqldata");

var app = builder.Build();

app.MapDefaultEndpoints();

if (app.Environment.IsDevelopment())
{
    // Retrieve an instance of the DbContext class and manually run migrations during startup
    using (var scope = app.Services.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<TicketContext>();
        context.Database.Migrate();
    }
}

次の手順

データベース のシード処理は、さまざまなアプリ開発シナリオで役立ちます。 これらの手法と、次のチュートリアルで示されているリソース実装を組み合わせてみます。