-
Notifications
You must be signed in to change notification settings - Fork 152
New migrations doc #838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
New migrations doc #838
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
53210aa
wip
CamSoper 22bb33e
Merge branch 'main' of https://github.com/dotnet/docs-aspire into cam…
CamSoper f9c9fa5
wip
CamSoper e135e3a
wip
CamSoper a24b5d1
wip
CamSoper 3254bed
more wip
CamSoper dfcc4a2
code reference
CamSoper 7b496be
Code ref
CamSoper adbebee
wip
CamSoper 1f601d1
wip
CamSoper 6e05124
fix code sample
CamSoper 005c724
wip
CamSoper 777dacf
First draft done
CamSoper 1787c54
lint fix
CamSoper 85e88c0
Merge branch 'main' of https://github.com/dotnet/docs-aspire into cam…
CamSoper a3ef4ca
Merge branch 'main' of https://github.com/dotnet/docs-aspire into cam…
CamSoper 2570e85
added toc and index
CamSoper 1a0b206
Apply suggestions from code review
CamSoper 6c75020
Update docs/database/ef-core-migrations.md
IEvangelist File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
--- | ||
title: Apply EF Core migrations in .NET Aspire | ||
description: Learn about how to to apply Entity Framework Core migrations in .NET Aspire | ||
ms.date: 3/20/2024 | ||
ms.topic: how-to | ||
--- | ||
|
||
# Apply Entity Framework Core migrations in .NET Aspire | ||
|
||
Since .NET Aspire apps use a containerized architecture, databases are ephemeral and can be recreated at any time. Entity Framework Core (EF Core) uses a feature called [migrations](/ef/core/managing-schemas/migrations) to create and update database schemas. Since databases are recreated when the app starts, you need to apply migrations to initialize the database schema each time your app starts. This is accomplished by registering a migration service project in your app that runs migrations during startup. | ||
|
||
In this tutorial, you learn how to configure .NET Aspire apps to run EF Core migrations during app startup. | ||
|
||
[!INCLUDE [aspire-prereqs](../includes/aspire-prereqs.md)] | ||
|
||
## Obtain the starter app | ||
|
||
This tutorial uses a sample app that demonstrates how to apply EF Core migrations in .NET Aspire. Use Visual Studio to clone [the sample app from GitHub](https://github.com/MicrosoftDocs/mslearn-aspire-starter) or use the following command: | ||
|
||
```bash | ||
git clone https://github.com/MicrosoftDocs/mslearn-aspire-starter | ||
``` | ||
|
||
The sample app is in the *SupportTicketApi* folder. Open the solution in Visual Studio or VS Code and take a moment to review the sample app and make sure it runs before proceeding. The sample app is a rudimentary support ticket API, and it contains the following projects: | ||
|
||
- **SupporTicketApi.Api**: The ASP.NET Core project that hosts the API. | ||
- **SupportTicketApi.Data**: Contains the EF Core contexts and models. | ||
- **SupportTicketApi.AppHost**: Contains the Aspire app host and configuration. | ||
- **SupportTicketApi.ServiceDefaults**: Contains the default service configurations. | ||
|
||
Run the app to ensure it works as expected. From the Aspire dashboard, select the **https** Swagger endpoint and test the API's **GET /api/SupportTickets** endpoint by expanding the operation and selecting **Try it out**. Select **Execute** to send the request and view the response: | ||
CamSoper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```json | ||
[ | ||
{ | ||
"id": 1, | ||
"title": "Initial Ticket", | ||
"description": "Test ticket, please ignore." | ||
} | ||
] | ||
``` | ||
|
||
## Create migrations | ||
|
||
Start by creating some migrations to apply. | ||
|
||
1. Open a terminal (<kbd>Ctrl</kbd>+<kbd>\`</kbd> in Visual Studio). | ||
1. Set *SupportTicketApi\SupportTicketApi.Api* as the current directory. | ||
1. Use the [`dotnet ef` command-line tool](https://learn.microsoft.com/ef/core/managing-schemas/migrations/#install-the-tools) to create a new migration to capture the initial state of the database schema: | ||
IEvangelist marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```dotnetcli | ||
dotnet ef migrations add InitialCreate --project ..\SupportTicketApi.Data\SupportTicketApi.Data.csproj | ||
``` | ||
|
||
The proceeding command: | ||
|
||
- Runs EF Core migration command-line tool in the *SupportTicketApi.Api* directory. `dotnet ef` is run in this location because the API service is where the DB context is used. | ||
- Creates a migration named *InitialCreate*. | ||
- Creates the migration in the in the *Migrations* folder in the *SupportTicketApi.Data* project. | ||
|
||
1. Modify the model so that it includes a new property. Open *SupportTicketApi.Data\Models\SupportTicket.cs* and add a new property to the `SupportTicket` class: | ||
|
||
:::code source="~/aspire-docs-samples-solution/SupportTicketApi/SupportTicketApi.Data/Models/SupportTicket.cs" range="5-13" highlight="8" ::: | ||
|
||
1. Create another new migration to capture the changes to the model: | ||
|
||
```dotnetcli | ||
dotnet ef migrations add AddCompleted --project ..\SupportTicketApi.Data\SupportTicketApi.Data.csproj | ||
``` | ||
|
||
Now you've got some migrations to apply. Next, you'll create a migration service that applies these migrations during app startup. | ||
|
||
## Create the migration service | ||
|
||
To run the migrations at startup, you need to create a service that applies the migrations. | ||
|
||
1. Add a new Worker Service project to the solution. If using Visual Studio, right-click the solution in Solution Explorer and select **Add** > **New Project**. Select **Worker Service** and name the project *SupportTicketApi.MigrationService*. If using the command line, use the following commands from the solution directory: | ||
|
||
```dotnetcli | ||
dotnet new worker -n SupportTicketApi.MigrationService | ||
dotnet sln add SupportTicketApi.MigrationService | ||
``` | ||
|
||
1. Add the *SupportTicketApi.Data* and *SupportTicketApi.ServiceDefaults* project references to the *SupportTicketApi.MigrationService* project using Visual Studio or the command line: | ||
|
||
```dotnetcli | ||
dotnet add SupportTicketApi.MigrationService reference SupportTicketApi.Data | ||
dotnet add SupportTicketApi.MigrationService reference SupportTicketApi.ServiceDefaults | ||
``` | ||
|
||
1. Add the *Aspire.Microsoft.EntityFrameworkCore.SqlServer* NuGet package reference to the *SupportTicketApi.MigrationService* project using Visual Studio or the command line: | ||
|
||
```dotnetcli | ||
dotnet add package Aspire.Microsoft.EntityFrameworkCore.SqlServer | ||
``` | ||
|
||
1. Replace the contents of the *Worker.cs* file in the *SupportTicketApi.MigrationService* project with the following code: | ||
|
||
:::code source="~/aspire-docs-samples-solution/SupportTicketApi/SupportTicketApi.MigrationService/Worker.cs" ::: | ||
|
||
In the preceding code: | ||
|
||
- The `ExecuteAsync` method is called when the worker starts. It in turn performs the following steps: | ||
1. Gets a reference to the `TicketContext` service from the service provider. | ||
1. Calls `EnsureDatabaseAsync` to create the database if it doesn't exist. | ||
1. Calls `RunMigrationAsync` to apply any pending migrations. | ||
1. Calls `SeedDataAsync` to seed the database with initial data. | ||
1. Stops the worker with `StopApplication`. | ||
- The `EnsureDatabaseAsync`, `RunMigrationAsync`, and `SeedDataAsync` methods all encapsulate their respective database operations using execution strategies to handle transient errors that may occur when interacting with the database. To learn more about execution strategies, see [Connection Resiliency](/ef/core/miscellaneous/connection-resiliency). | ||
|
||
## Add the migration service to the Aspire orchestration | ||
CamSoper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The migration service is created, but it needs to be added to the Aspire app host so that it runs when the app starts. | ||
CamSoper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
1. In the *SupportTicketApi.AppHost* project, open the *Program.cs* file. | ||
1. Add the following highlighted code to the `ConfigureServices` method: | ||
|
||
:::code source="~/aspire-docs-samples-solution/SupportTicketApi/SupportTicketApi.AppHost/Program.cs" highlight="9-10" ::: | ||
|
||
This enlists the *SupportTicketApi.MigrationService* project as a service in the Aspire app host. | ||
CamSoper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
> [!IMPORTANT] | ||
> If you are using Visual Studio, and you selected the **Enlist in Aspire orchestration** option when creating the Worker Service project, similar code is added automatically with the service name `supportticketapi-migrationservice`. Replace that code with the preceding code. | ||
|
||
## Remove existing seeding code | ||
|
||
Since the migration service seeds the database, you should remove the existing data seeding code from the API project. | ||
|
||
1. In the *SupportTicketApi.Api* project, open the *Program.cs* file. | ||
1. Delete the highlighted lines. | ||
|
||
:::code source="~/aspire-docs-samples-main/SupportTicketApi/SupportTicketApi.Api/Program.cs" range="20-36" highlight="6-16" ::: | ||
|
||
## Test the migration service | ||
|
||
Now that the migration service is configured, run the app to test the migrations. | ||
|
||
1. Run the app and observe the SupportTicketApi dashboard. | ||
1. After a short wait, the `migrations` service state will display **Finished**. | ||
|
||
:::image type="content" source="media/ef-core-migrations/dashboard-post-migration.png" lightbox="media/ef-core-migrations/dashboard-post-migration.png" alt-text="A screenshot of the Aspire dashboard with the migration service in a Finished state." ::: | ||
CamSoper marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
1. Select the **View** link on the migration service to investigate the logs showing the SQL commands that were executed. | ||
|
||
## Get the code | ||
|
||
You can find the [completed sample app on GitHub](https://github.com/MicrosoftDocs/aspire-docs-samples/tree/solution/SupportTicketApi). |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.