Gegevens in een database invoeren met behulp van .NET.NET Aspire
In dit artikel leert u hoe u .NET.NET Aspire projecten configureert om gegevens in een database te seeden tijdens het opstarten van de app. Met .NET Aspire kunt u gegevens inzaaien met behulp van databasescripts of Entity Framework Core voor algemene platforms zoals SQL Server, PostgreSQL en MySQL.
Wanneer gegevens te seeden
Door gegevens vooraf te seeden, worden databasetabellen gevuld met rijen gegevens, zodat ze klaar zijn om te testen via uw app. U kunt gegevens voor de volgende scenario's seeden:
- Ontwikkel en test handmatig verschillende functies van uw app op basis van een zinvolle set gegevens, zoals een productcatalogus of lijst met klanten.
- Voer testsuites uit om te controleren of functies zich op een specifieke manier gedragen met een bepaalde set gegevens.
Het handmatig invoeren van gegevens is vermoeiend en tijdrovend, dus u moet het proces zo mogelijk automatiseren. Gebruik volumes om databasescripts uit te voeren voor .NET.NET Aspire projecten tijdens het opstarten. U kunt uw database ook seeden met behulp van hulpprogramma's zoals Entity Framework Core, die veel onderliggende zaken voor u regelt.
Inzicht in gecontaineriseerde databases
Standaard zijn .NET.NET Aspire database-integraties afhankelijk van in containers geplaatste databases, waardoor de volgende uitdagingen ontstaan bij het seeden van gegevens:
- De containers van .NET.NET Aspire worden elke keer dat de app opnieuw wordt opgestart, vernietigd en opnieuw gemaakt; dit betekent dat u de database standaard opnieuw moet populeren telkens wanneer de app opnieuw wordt opgestart.
- Afhankelijk van de geselecteerde databasetechnologie kan het nieuwe containerexemplaar een standaarddatabase maken of niet. Dit betekent dat u mogelijk ook de database zelf moet maken.
- Zelfs als er een standaarddatabase bestaat, heeft deze waarschijnlijk niet de gewenste naam of het gewenste schema voor uw specifieke app.
.NET .NET Aspire stelt u in staat deze uitdagingen op te lossen met behulp van volumes en enkele configuraties om gegevens effectief voor te bereiden.
Seed-gegevens met behulp van volumes en SQL-scripts
Volumes zijn de aanbevolen manier om automatisch containerdatabases te seeden bij het gebruik van SQL-scripts. Volumes kunnen gegevens voor meerdere containers tegelijk opslaan, hoge prestaties bieden en eenvoudig back-ups maken of migreren. Met .NET.NET Aspireconfigureert u een volume voor elke resourcecontainer met behulp van de methode ContainerResourceBuilderExtensions.WithBindMount, die drie parameters accepteert:
- Bron: Het bronpad van de volume-mount, wat de fysieke locatie op uw host is.
- Doelpad: het pad in de container met de gegevens die u wilt opslaan.
Bekijk de volgende volumeconfiguratiecode uit een Program.cs-bestand in een voorbeeldproject 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 dit voorbeeld configureren de parameters van de .WithBindMount
methode het volgende:
-
../DatabaseContainers.ApiService/data/postgres
stelt een pad in naar het SQL-script in uw lokale project dat u in de container wilt uitvoeren om gegevens te seeden. -
/docker-entrypoint-initdb.d
stelt het pad in op een toegangspunt in de container, zodat uw script wordt uitgevoerd tijdens het opstarten van de container.
Met het SQL-script waarnaar wordt verwezen in ../DatabaseContainers.ApiService/data/postgres
wordt een Todos
tabel gemaakt en gezaaid:
-- 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;
Het script wordt uitgevoerd tijdens het opstarten telkens wanneer een nieuwe containerinstantie wordt gemaakt.
Voorbeelden van database-seeding
In de volgende voorbeelden ziet u hoe u gegevens kunt seeden met behulp van SQL-scripts en -configuraties die zijn toegepast met behulp van de .WithBindMount
methode voor verschillende databasetechnologieën:
Notitie
Ga naar de databasecontainervoorbeeld-app om de volledige project- en bestandsstructuur voor elke databaseoptie weer te geven.
De configuratiecode in de . AppHostProgram.cs bestand koppelt de vereiste databasebestanden en -mappen en configureert een invoerpunt, zodat deze worden uitgevoerd tijdens het opstarten.
// SQL Server container is configured with an auto-generated password by default
// but doesn't support any auto-creation of databases or running scripts on startup so we have to do it manually.
var sqlserver = builder.AddSqlServer("sqlserver")
// Mount the init scripts directory into the container.
.WithBindMount("./sqlserverconfig", "/usr/config")
// Mount the SQL scripts directory into the container so that the init scripts run.
.WithBindMount("../DatabaseContainers.ApiService/data/sqlserver", "/docker-entrypoint-initdb.d")
// Run the custom entrypoint script on startup.
.WithEntrypoint("/usr/config/entrypoint.sh")
// 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);
Het entrypoint.sh script bevindt zich in de gekoppelde ./sqlserverconfig
projectmap en wordt uitgevoerd wanneer de container wordt gestart. Het script start SQL Server en controleert of het wordt uitgevoerd.
#!/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
Met het init.sql SQL-script dat zich in de gekoppelde ../DatabaseContainers.ApiService/data/sqlserver
projectmap bevindt, worden de database en tabellen gemaakt.
-- 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
Seedgegevens met behulp van Entity Framework Core
U kunt ook gegevens in .NET Aspire projecten seeden met behulp van Entity Framework Core door expliciet migraties uit te voeren tijdens het opstarten. Entity Framework Core verwerkt onderliggende databaseverbindingen en het maken van schema's voor u, waardoor u geen volumes hoeft te gebruiken of SQL-scripts hoeft uit te voeren tijdens het opstarten van de container.
Belangrijk
Deze typen configuraties moeten alleen worden uitgevoerd tijdens de ontwikkeling. Zorg er dus voor dat u een voorwaarde toevoegt waarmee de huidige omgevingscontext wordt gecontroleerd.
Voeg de volgende code toe aan het Program.cs-bestand van uw API Service project.
// 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();
}
}
Volgende stappen
Database-seeding is handig in verschillende scenario's voor app-ontwikkeling. Probeer deze technieken te combineren met de resource-implementaties die in de volgende handleidingen worden gedemonstreerd.