Skip to content
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

Improvements to migration docs #2430

Merged
merged 5 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions entity-framework/core/managing-schemas/migrations/applying.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---
title: Applying Migrations - EF Core
author: bricelam
ms.author: bricelam
ms.date: 05/06/2020
uid: core/managing-schemas/migrations/applying
---
# Applying Migrations

Once your migrations have been added, they need to be deployed and applied to your databases. There are various strategies for doing this, with some being more appropriate for production environments, and others for the development lifecycle.

> [!NOTE]
> Whatever your deployment strategy, always inspect the generated migrations and test them applying to a production database. A migration may drop a column when the intent was to rename it, or may fail for various when applied to a database.

## SQL scripts

The recommended way to deploy migrations to a production database is by generating SQL scripts. The advantages of this strategy include the following:

* SQL scripts can be reviewed for accuracy; this is important since applying schema changes to production databases is a potentially dangerous operation that could involve data loss.
* In some cases, the scripts can be tuned to fit the specific needs of a production database.
* SQL scripts can be used in conjunction with a deployment technology.
* SQL scripts can be provided to a DBA, and can be managed and archived separately.

### [.NET Core CLI](#tab/dotnet-core-cli)

#### Basic Usage

The following generates a SQL script from a blank database to the latest migration:

```dotnetcli
dotnet ef migrations script
```

#### With From (to implied)

The following generates a SQL script from the given migration to the latest migration.

```dotnetcli
dotnet ef migrations script AddNewTables
```

#### With From and To

The following generates a SQL script from the `from` migration to the specified `to` migration.

```dotnetcli
dotnet ef migrations script AddNewTables AddAuditTable
```

You can use a `from` that is newer than the `to` in order to generate a rollback script. *Please take note of potential data loss scenarios.*

### [Visual Studio](#tab/vs)

The following generates a SQL script from a blank database to the latest migration:

#### Basic Usage

``` powershell
Script-Migration
```

#### With From (to implied)

The following generates a SQL script from this migration to the latest migration.

```powershell
Script-Migration AddNewTables
```

#### With From and To

The following generates a SQL script from the `from` migration to the specified `to` migration.

```powershell
Script-Migration AddNewTables AddAuditTable
```
You can use a `from` that is newer than the `to` in order to generate a rollback script. *Please take note of potential data loss scenarios.*

***

There are several options to this command.

The **from** migration should be the last migration applied to the database before running the script. If no migrations have been applied, specify `0` (this is the default).

The **to** migration is the last migration that will be applied to the database after running the script. This defaults to the last migration in your project.

## Idempotent SQL scripts

The SQL scripts generated above can only be applied to change your schema from one migration to another; it is your responsibility to apply the script appropriately, and only to database in the correct migration state. EF Core also supports generating **idempotent** scripts, which internally check which migrations have already been applied, and only apply missing ones. This is useful if you don't exactly know what the last migration applied to the database was, or if you are deploying to multiple databases that may each be at a different migration.

The following generates idempotent migrations:

#### [.NET Core CLI](#tab/dotnet-core-cli)

```dotnetcli
dotnet ef migrations add AddNewTables --idempotent
roji marked this conversation as resolved.
Show resolved Hide resolved
```

#### [Visual Studio](#tab/vs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should something go here about accessing the Package Management Console, for the context of where these commands are run from?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean general information on the PMC and how to install the tools, right? If so, we have the dedicated page on that, and there's the "install the tools" paragraph (with a link to the dedicated page) in the migration's index.html. Do you think we need something more?


``` powershell
Add-Migration AddNewTables -Idempotent
```

> [!WARNING]
> Idempotent scripts have some known limitations and will not work in all scenarios.
roji marked this conversation as resolved.
Show resolved Hide resolved

***

## Command-line tools

The EF command-line tools can be used to apply migrations to a database. While productive for local development and testing of migrations, this approach is inappropriate for management of production databases:

* The SQL commands are applied directly by the tool, without giving the developer a change to inspect or modify them. This can be dangerous in a production environment.
* The .NET SDK and the EF tool must be installed on production servers.

### [.NET Core CLI](#tab/dotnet-core-cli)

The following updates your database to the latest migration:

```dotnetcli
dotnet ef database update
```

The following updates your database to a given migration:

```dotnetcli
dotnet ef database update AddNewTables
```

### [Visual Studio](#tab/vs)

The following updates your database to the latest migration:

``` powershell
Update-Database
```

The following updates your database to a given migration:

``` powershell
Update-Database AddNewTables
```

***

Note that this can be used to roll back to an earlier migration as well. *Please take note of potential data loss scenarios.*

For more information on applying migrations via the command-line tools, see the [EF Core tools reference](xref:core/miscellaneous/cli/index).

## Apply migrations at runtime
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there guidance on how to create a standalone executable for this that would be an interim solution until the new bundling features are ready? It seems some companies will build a console app just to host the migrations code and deploy that to run as part of CI/CD separate from the web app consuming the database.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not specifically aware of people going to those lengths (but maybe @bricelam is)... Typically people either deploy via SQL scripts (which is what we usually recommend), or they just stick Migrate in their program startup, which is what we try to discourage...

I guess that since @bricelam is specifically working on bundles, we may want to hold off for now and just document that once it lands...


It's possible for the application itself to apply migrations programmatically, typically during startup. While productive for local development and testing of migrations, this approach is inappropriate for management of production databases:

* If multiple instances of your application are running, both applications could attempt to apply the migration concurrently and fail (or worse, cause data corruption).
* Similarly, if an application is accessing the database while another application migrates it, this can cause severe issues.
* This requires the application to have elevated access to modify the database schema. It's generally good practice to limit the application's database permissions in production.
* It's important to be able to roll back an applied migration in case of an issue. The other strategies provide this easily and out of the box.
* The SQL commands are applied directly by the program, without giving the developer a change to inspect or modify them. This can be dangerous in a production environment.

To apply migrations programmatically, call `myDbContext.Database.Migrate()`. For example, a typical ASP.NET application can do the following:

```c#
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();

using (var scope = host.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
db.Database.Migrate();
}

host.Run();
}
```

Note that `Migrate()` builds on top of the `IMigrator` service, which can be used for more advanced scenarios. Use `myDbContext.GetInfrastructure().GetService<IMigrator>()` to access it.

> [!WARNING]
>
> * Carefully consider before using this approach in production. Experience has shown that the simplicity of this deployment strategy is outweighed by the problem it brings. Consider using SQL scripts instead.
> * Don't call `EnsureCreated()` before `Migrate()`. `EnsureCreated()` bypasses Migrations to create the schema, which causes `Migrate()` to fail.
Loading