Aplikujte Entity Framework Core migrace v .NET Aspire
Vzhledem k tomu, že projekty .NET.NET Aspire používají kontejnerizovanou architekturu, databáze jsou dočasné a je možné je kdykoli znovu vytvořit. Entity Framework Core (EF Core) používá funkci označovanou jako migrace k vytváření a aktualizaci schémat databáze. Vzhledem k tomu, že se databáze po spuštění aplikace znovu vytvoří, musíte při každém spuštění aplikace použít migrace, abyste inicializovali schéma databáze. Toho dosáhnete tak, že ve své aplikaci zaregistrujete projekt služby migrace, který spouští migrace během spouštění.
V tomto kurzu se dozvíte, jak nakonfigurovat .NET Aspire projekty tak, aby spouštěly EF Core migrace během spouštění aplikace.
Požadavky
Pokud chcete pracovat s .NET.NET Aspire, potřebujete místně nainstalovat následující:
- .NET 8.0 nebo .NET 9.0
- Modul runtime kontejneru kompatibilní s OCI, například:
- Docker Desktop nebo Podman. Další informace najdete v tématu běhové prostředí kontejneru.
- Integrované vývojové prostředí (IDE) nebo editor kódu, například:
- Visual Studio 2022 verze 17.9 nebo novější (volitelné)
-
Visual Studio Code (volitelné)
- C# Dev Kit: Rozšíření (volitelné)
- JetBrains Rider s .NETpluginem.NET Aspire (volitelně)
Další informace najdete v tématu .NET.NET Aspire nastavení a nástrojea .NET.NET Aspire SDK.
Získání úvodní aplikace
Tento kurz používá ukázkovou aplikaci, která předvádí, jak aplikovat EF Core migrace v .NET Aspire. Pomocí Visual Studio naklonujte ukázkovou aplikaci z GitHub nebo použijte následující příkaz:
git clone https://github.com/MicrosoftDocs/aspire-docs-samples/
Ukázková aplikace je ve složce SupportTicketApi. Otevřete řešení v Visual Studio nebo VS Code a chvíli si prohlédněte ukázkovou aplikaci a před pokračováním se ujistěte, že se spustí. Příkladová aplikace je jednoduché API pro systém podpory prostřednictvím tiketů, a obsahuje následující projekty:
- SupportTicketApi.Api: Projekt ASP.NET Core, který je hostitelem rozhraní API.
- SupportTicketApi.AppHost: Obsahuje aplikační hostitel .NETa nastavení konfigurace.NET Aspire.
- SupportTicketApi.Data: Obsahuje kontexty a modely EF Core.
- SupportTicketApi.ServiceDefaults: Obsahuje výchozí konfigurace služby.
Spusťte aplikaci, abyste měli jistotu, že funguje podle očekávání. Na řídicím panelu .NET.NET Aspire počkejte, až budou všechny prostředky spuštěné a funkční. Poté vyberte koncový bod https Swagger a otestujte koncový bod API GET /api/SupportTickets rozbalením operace a výběrem možnosti Vyzkoušet. Poté vyberte Spustit pro odeslání požadavku a zobrazení odpovědi:
[
{
"id": 1,
"title": "Initial Ticket",
"description": "Test ticket, please ignore."
}
]
Zavřete karty prohlížeče, které zobrazují koncový bod Swagger a řídicí panel .NET.NET Aspire, a poté zastavte ladění.
Vytvořte migrace
Začněte vytvořením některých migrací, které se mají použít.
Otevřete terminál (Ctrl+` v Visual Studio).
Nastavte SupportTicketApi\SupportTicketApi.Api jako aktuální adresář.
Pomocí nástroje příkazového řádku
dotnet ef
vytvořte novou migraci, která zachytí počáteční stav schématu databáze:dotnet ef migrations add InitialCreate --project ..\SupportTicketApi.Data\SupportTicketApi.Data.csproj
Příkaz pro pokračování:
- Spustí migrační nástroj příkazového řádku EF Core v adresáři SupportTicketApi.Api.
dotnet ef
se spouští v tomto umístění, protože služba API je místem, kde se používá kontext databáze. - Vytvoří migraci s názvem InitialCreate.
- Vytvoří migraci ve složce Migrations v projektu SupportTicketApi.Data.
- Spustí migrační nástroj příkazového řádku EF Core v adresáři SupportTicketApi.Api.
Upravte model tak, aby zahrnoval novou vlastnost. Otevřete SupportTicketApi.Data\Models\SupportTicket.cs a přidejte novou vlastnost do třídy
SupportTicket
:public sealed class SupportTicket { public int Id { get; set; } [Required] public string Title { get; set; } = string.Empty; [Required] public string Description { get; set; } = string.Empty; public bool Completed { get; set; } }
Vytvořte další novou migraci, která zachytí změny modelu:
dotnet ef migrations add AddCompleted --project ..\SupportTicketApi.Data\SupportTicketApi.Data.csproj
Teď máte nějaké migrace, které musíte provést. V dalším kroku vytvoříte službu migrace, která tyto migrace použije při spuštění aplikace.
Vytvoření služby migrace
Pokud chcete spustit migrace při spuštění, musíte vytvořit službu, která migraci použije.
Přidejte do řešení nový projekt Worker Service. Pokud používáte Visual Studio, klikněte pravým tlačítkem na řešení v Průzkumníku řešení a vyberte Add>New Project. Vyberte Worker Service, pojmenujte projekt SupportTicketApi.MigrationService a cíl .NET 8.0. Pokud používáte příkazový řádek, použijte následující příkazy z adresáře řešení:
dotnet new worker -n SupportTicketApi.MigrationService -f "net8.0" dotnet sln add SupportTicketApi.MigrationService
Pomocí SupportTicketApi.Data nebo příkazového řádku přidejte do projektu SupportTicketApi.ServiceDefaults odkazy na SupportTicketApi.MigrationService a Visual Studio projektu:
dotnet add SupportTicketApi.MigrationService reference SupportTicketApi.Data dotnet add SupportTicketApi.MigrationService reference SupportTicketApi.ServiceDefaults
Přidejte referenci na balíček NuGet 📦Aspire.Microsoft.EntityFrameworkCore.SqlServer do projektu SupportTicketApi.MigrationService pomocí Visual Studio nebo příkazového řádku.
cd SupportTicketApi.MigrationService dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer -v "9.1.0"
Přidejte zvýrazněné řádky do souboru Program.cs v projektu SupportTicketApi.MigrationService:
using SupportTicketApi.Data.Contexts; using SupportTicketApi.MigrationService; var builder = Host.CreateApplicationBuilder(args); builder.AddServiceDefaults(); builder.Services.AddHostedService<Worker>(); builder.Services.AddOpenTelemetry() .WithTracing(tracing => tracing.AddSource(Worker.ActivitySourceName)); builder.AddSqlServerDbContext<TicketContext>("sqldata"); var host = builder.Build(); host.Run();
V předchozím kódu:
- Metoda rozšíření
AddServiceDefaults
přidává výchozí funkce služby. - Metoda rozšíření
AddOpenTelemetry
konfiguruje funkčnost OpenTelemetry. - Metoda rozšíření
AddSqlServerDbContext
přidá službuTicketContext
do kolekce služeb. Tato služba se používá ke spouštění migrací a naplnění databáze počátečními daty.
- Metoda rozšíření
Obsah souboru Worker.cs v projektu SupportTicketApi.MigrationService nahraďte následujícím kódem:
using System.Diagnostics; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using OpenTelemetry.Trace; using SupportTicketApi.Data.Contexts; using SupportTicketApi.Data.Models; namespace SupportTicketApi.MigrationService; public class Worker( IServiceProvider serviceProvider, IHostApplicationLifetime hostApplicationLifetime) : BackgroundService { public const string ActivitySourceName = "Migrations"; private static readonly ActivitySource s_activitySource = new(ActivitySourceName); protected override async Task ExecuteAsync(CancellationToken cancellationToken) { using var activity = s_activitySource.StartActivity("Migrating database", ActivityKind.Client); try { using var scope = serviceProvider.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService<TicketContext>(); await RunMigrationAsync(dbContext, cancellationToken); await SeedDataAsync(dbContext, cancellationToken); } catch (Exception ex) { activity?.RecordException(ex); throw; } hostApplicationLifetime.StopApplication(); } private static async Task RunMigrationAsync(TicketContext dbContext, CancellationToken cancellationToken) { var strategy = dbContext.Database.CreateExecutionStrategy(); await strategy.ExecuteAsync(async () => { // Run migration in a transaction to avoid partial migration if it fails. await dbContext.Database.MigrateAsync(cancellationToken); }); } private static async Task SeedDataAsync(TicketContext dbContext, CancellationToken cancellationToken) { SupportTicket firstTicket = new() { Title = "Test Ticket", Description = "Default ticket, please ignore!", Completed = true }; var strategy = dbContext.Database.CreateExecutionStrategy(); await strategy.ExecuteAsync(async () => { // Seed the database await using var transaction = await dbContext.Database.BeginTransactionAsync(cancellationToken); await dbContext.Tickets.AddAsync(firstTicket, cancellationToken); await dbContext.SaveChangesAsync(cancellationToken); await transaction.CommitAsync(cancellationToken); }); } }
V předchozím kódu:
- Metoda
ExecuteAsync
je volána při spuštění pracovního procesu. Následně provede následující kroky:- Získá odkaz na službu
TicketContext
od poskytovatele služeb. - Volá
RunMigrationAsync
, aby se použily všechny čekající migrace. - Volání
SeedDataAsync
pro naplnění databáze počátečními daty. - Zastaví pracovníka pomocí
StopApplication
.
- Získá odkaz na službu
-
RunMigrationAsync
aSeedDataAsync
metody zapouzdřují své příslušné databázové operace pomocí strategií vykonávání k řešení přechodných chyb, ke kterým může dojít při interakci s databází. Další informace o strategiích provádění najdete v tématu Odolnost připojení.
- Metoda
Přidání služby migrace do orchestrátoru
Služba migrace se vytvoří, ale je potřeba ji přidat do hostitele aplikace .NET.NET Aspire, aby se spustila při spuštění aplikace.
V projektu SupportTicketApi.AppHost otevřete soubor Program.cs.
Do metody
ConfigureServices
přidejte následující zvýrazněný kód:var builder = DistributedApplication.CreateBuilder(args); var sql = builder.AddSqlServer("sql", port: 14329) .WithEndpoint(name: "sqlEndpoint", targetPort: 14330) .AddDatabase("sqldata"); builder.AddProject<Projects.SupportTicketApi_Api>("api") .WithReference(sql) .WaitFor(sql); builder.AddProject<Projects.SupportTicketApi_MigrationService>("migrations") .WithReference(sql) .WaitFor(sql); builder.Build().Run();
Tím se projekt SupportTicketApi.MigrationService začlení jako služba v aplikaci hostitele .NET.NET Aspire.
Pokud kód nemůže vyřešit projekt služby migrace, přidejte do projektu AppHost odkaz na projekt služby migrace:
dotnet add SupportTicketApi.AppHost reference SupportTicketApi.MigrationService
Důležitý
Pokud používáte Visual Studioa při vytváření projektu Enlist in Aspire orchestration jste vybrali možnost Worker Service, přidá se podobný kód automaticky s názvem služby
supportticketapi-migrationservice
. Nahraďte tento kód předchozím kódem.
Odebrání existujícího počátečního kódu
Protože služba migrace naplní databázi, měli byste z projektu rozhraní API odebrat stávající kód pro naplnění dat.
V projektu SupportTicketApi.Api otevřete soubor Program.cs.
Odstraňte zvýrazněné čáry.
if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); using (var scope = app.Services.CreateScope()) { var context = scope.ServiceProvider.GetRequiredService<TicketContext>(); context.Database.EnsureCreated(); if(!context.Tickets.Any()) { context.Tickets.Add(new SupportTicket { Title = "Initial Ticket", Description = "Test ticket, please ignore." }); context.SaveChanges(); } } }
Testování služby migrace
Teď, když je služba migrace nakonfigurovaná, spusťte aplikaci a otestujte migrace.
Spusťte aplikaci a sledujte řídicí panel SupportTicketApi.
Po krátkém čekání bude stav služby
migrations
zobrazen jako Dokončeno.Vyberte ikonu Console logs ve službě migrace a prozkoumejte protokoly zobrazující spuštěné příkazy SQL.
Získání kódu
Na
Další ukázkový kód
Ukázková aplikace Aspire Shop používá tento přístup pro aplikaci migrací. Podívejte se na projekt AspireShop.CatalogDbManager
pro implementaci služby migrace.