Freigeben über


Seed-Daten in einer Datenbank mithilfe von .NETund.NET Aspire

In diesem Artikel erfahren Sie, wie Sie .NET.NET Aspire Projekte so konfigurieren, dass während des Anwendungsstarts Seeddaten in eine Datenbank eingefügt werden. mit .NET Aspire können Sie Daten mithilfe von Datenbankskripts oder Entity Framework Core für gängige Plattformen wie SQL Server, PostgreSQL und MySQLseedieren.

Wann Daten eingepflegt werden sollen

Seeding-Daten füllen Datenbanktabellen mit Datenzeilen vor, damit sie über Ihre App getestet werden können. Möglicherweise möchten Sie Seeddaten für die folgenden Szenarien erstellen:

  • Entwickeln und testen Sie verschiedene Features Ihrer App manuell anhand einer aussagekräftigen Datenmenge, z. B. einem Produktkatalog oder einer Kundenliste.
  • Führen Sie Testsuiten aus, um zu überprüfen, ob sich Features mit einer bestimmten Datenmenge auf eine bestimmte Weise verhalten.

Das manuelle Initialisieren von Daten ist mühsam und zeitaufwändig, sodass Sie den Prozess nach Möglichkeit automatisieren sollten. Verwenden Sie Volumes, um Datenbankskripts für .NET.NET Aspire Projekte während des Starts auszuführen. Sie können Ihre Datenbank auch mit Tools wie Entity Framework Corebefüllen, die viele zugrunde liegende Aufgaben für Sie behandeln.

Grundlegendes zu containerisierten Datenbanken

Standardmäßig basieren .NET.NET Aspire Datenbankintegrationen auf containerisierte Datenbanken, die beim Versuch, Seeddaten zu starten, folgende Herausforderungen darstellen:

  • .NET .NET Aspire zerstört und erstellt Container jedes Mal neu, wenn die App neu gestartet wird, was bedeutet, dass Sie standardmäßig Ihre Datenbank bei jedem Neustart der App neu initialisieren müssen.
  • Je nach ausgewählter Datenbanktechnologie erstellt die neue Containerinstanz möglicherweise eine Standarddatenbank, was bedeutet, dass Sie gegebenenfalls die Datenbank selbst erstellen müssen.
  • Selbst wenn eine Standarddatenbank vorhanden ist, hat sie wahrscheinlich nicht den gewünschten Namen oder das gewünschte Schema für Ihre spezifische App.

mit .NET.NET Aspire können Sie diese Herausforderungen mithilfe von Volumes und einigen Konfigurationen lösen, um Daten effektiv zu seeden.

Seed-Daten mit Volumes und SQL-Skripts

Volumes sind die empfohlene Methode zum automatischen Seeden von containerisierten Datenbanken bei Verwendung von SQL-Skripts. Volumes können Daten für mehrere Container gleichzeitig speichern, hohe Leistung bieten und einfach gesichert oder migriert werden. Mit .NET.NET Aspirekonfigurieren Sie ein Volume für jeden Ressourcencontainer mithilfe der ContainerResourceBuilderExtensions.WithBindMount-Methode, die drei Parameter akzeptiert:

  • Source: Der Quellpfad des Volume-Mounts, welcher der physische Speicherort auf Ihrem Host ist.
  • Ziel-: Der Zielpfad im Container der Daten, die Sie speichern möchten.

Betrachten Sie den folgenden Volumenkonfigurationscode aus der Datei Program.cs in einem Beispielprojekt AppHost:

var todosDbName = "Todos";
var todosDb = builder.AddPostgres("postgres")
    .WithEnvironment("POSTGRES_DB", todosDbName)
    .WithBindMount(
        "../DatabaseContainers.ApiService/data/postgres",
        "/docker-entrypoint-initdb.d")
    .AddDatabase(todosDbName);

In diesem Beispiel konfigurieren die .WithBindMount Methodenparameter Folgendes:

  • ../DatabaseContainers.ApiService/data/postgres legt einen Pfad zu einem SQL-Skript in Ihrem lokalen Projekt fest, das Sie im Container ausführen möchten, um Daten zu initialisieren.
  • /docker-entrypoint-initdb.d legt den Pfad zu einem Einstiegspunkt im Container fest, sodass Ihr Skript während des Containerstarts ausgeführt wird.

Das referenzierte SQL-Skript, das sich in ../DatabaseContainers.ApiService/data/postgres befindet, erstellt und füllt eine Todos-Tabelle.

-- Postgres init script

-- Create the Todos table
CREATE TABLE IF NOT EXISTS Todos
(
    Id SERIAL PRIMARY KEY,
    Title text UNIQUE NOT NULL,
    IsComplete boolean NOT NULL DEFAULT false
);

-- Insert some sample data into the Todos table
INSERT INTO Todos (Title, IsComplete)
VALUES
    ('Give the dog a bath', false),
    ('Wash the dishes', false),
    ('Do the groceries', false)
ON CONFLICT DO NOTHING;

Das Skript wird beim Start jedes Mal ausgeführt, wenn eine neue Containerinstanz erstellt wird.

Beispiele für die Initialisierung von Datenbanken

Die folgenden Beispiele veranschaulichen, wie Daten mithilfe von SQL-Skripts und -Konfigurationen, die mithilfe der .WithBindMount-Methode für verschiedene Datenbanktechnologien angewendet werden, seeden:

Anmerkung

Besuchen Sie die Beispiel-App für Datenbankcontainer , um die vollständige Projekt- und Dateistruktur für jede Datenbankoption anzuzeigen.

Der Konfigurationscode in der .AppHostProgram.cs Datei bindet die erforderlichen Datenbankdateien und -ordner ein und konfiguriert einen Entry-Point, damit sie während des Starts ausgeführt werden.

    .WithEnvironment("MYSQL_DATABASE", catalogDbName)
    // Mount the SQL scripts directory into the container so that the init scripts run.
    .WithBindMount("../DatabaseContainers.ApiService/data/mysql", "/docker-entrypoint-initdb.d")
    // 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 catalogDb = mysql.AddDatabase(catalogDbName);

// SQL Server container is configured with an auto-generated password by default

Das Skript entrypoint.sh befindet sich im eingehängten ./sqlserverconfig Projektordner und wird ausgeführt, wenn der Container startet. Das Skript startet SQL Server und überprüft, ob es läuft.

#!/bin/bash

# Adapted from: https://github.com/microsoft/mssql-docker/blob/80e2a51d0eb1693f2de014fb26d4a414f5a5add5/linux/preview/examples/mssql-customize/entrypoint.sh

# Start the script to create the DB and user
/usr/config/configure-db.sh &

# Start SQL Server
/opt/mssql/bin/sqlservr

Das init.sql SQL-Skript, das sich im bereitgestellten ../DatabaseContainers.ApiService/data/sqlserver Projektordner befindet, erstellt die Datenbank und Tabellen.

-- 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

Seed-Daten mithilfe von Entity Framework Core

Sie können auch Daten in .NET Aspire-Projekten mit Entity Framework Core bereitstellen, indem Sie während des Starts explizit Migrationen ausführen. Entity Framework Core behandelt zugrunde liegende Datenbankverbindungen und die Schemaerstellung für Sie, wodurch die Notwendigkeit beseitigt wird, Während des Containerstarts Volumes zu verwenden oder SQL-Skripts auszuführen.

Wichtig

Diese Konfigurationstypen sollten nur während der Entwicklung durchgeführt werden. Stellen Sie daher sicher, dass Sie eine bedingte Bedingung hinzufügen, die den aktuellen Umgebungskontext überprüft.

Fügen Sie den folgenden Code in die Datei Program.cs Ihres API Services Projekts ein.

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

Nächste Schritte

Datenbank-Seeding ist in einer Vielzahl von App-Entwicklungsszenarien nützlich. Versuchen Sie, diese Techniken mit den Ressourcenimplementierungen zu kombinieren, die in den folgenden Lernprogrammen veranschaulicht werden: