Picture: Microsoft

Entity Framework 3 - Migrations

Install EF Core 3 Migration tools

The tooling of the Entity Framework Core Migrations comes via NuGet (and dotnet tooling).

dotnet tool install --global dotnet-ef

This installs the latest version of the EFCore dotnet tooling.

To specify a version of the tooling, you can use:

dotnet tool install --global dotnet-ef --version 1.2.3

Update or reinstall EF Core 3 Migration tools

To update the tooling you can use:

dotnet tool update --global dotnet-ef

If the tooling is already installed, it automatically reinstalls the tooling.

Microsoft Windows [Version 10.0.18363.535]
(c) 2019 Microsoft Corporation. All rights reserved.

C:\Windows\system32>dotnet tool update --global dotnet-ef
Tool 'dotnet-ef' was reinstalled with the latest stable version (version '3.1.0').

C:\Windows\system32>

Hint: in DevOps environments like Azure DevOps you should always use the update command in your build steps. If the tooling is installed, it updates or reinstalls the tooling. If the tooling is missing, is installs the tools.

The install command would fail if the tooling is already installed, which is not the best behavior.

Setup Migration Context

My recommendation is to use a isolated migration project instead to keep all migration inside your application project.

  • MyCSharp.Portal - the main application domain project
  • MyCSharp.Portal.Database.Migrations - the database migration project

The migration project must be an executable project like a console application (netcoreapp3.1)!

To run migrations, you can create your own migration context. This context should inherit from your main application database context.

    public class MigrationEFCoreDbContext : EFCoreDbContext
    {
        public MigrationEFCoreDbContext(DbContextOptions<MigrationEFCoreDbContext> options)
            : base(options)
        {
            
        }
    }

The idea behind the migration application and migration context is:

  • separate executable migration application (e.g. DevOps)
  • avoid risky automatic migrations
  • isolated place to run specific migration operations

The migration Program.cs then could look like:

    public class Program
    {
        public static void Main(string[] args)
            => CreateHostBuilder(args).Build().Run();

        // EF Core uses this method at design time to access the DbContext
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddDbContext<MigrationEFCoreDbContext>(o =>
                        o.UseSqlServer("ConnectionString"));
                });
    }

Create Migration

To create a migration you can use the migration add <name> command:

// creates a new migration with the title "Init"
dotnet ef migrations add Init
C:\_s\MyCSharp\MyCSharpNET\src\MyCSharp.Portal.Database> dotnet ef migrations add Init
Build started...
Build succeeded.
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 3.1.0 initialized 'MyCSharpEFCoreMigrationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Done. To undo this action, use 'ef migrations remove'

Afterwards you will see a Migrations folder in your migrations project. This folder contains all migration-specific files.

    Directory: C:\_s\MyCSharp\MyCSharpNET\src\MyCSharp.Portal.Database\Migrations


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       24.12.2019     18:59          45422 20191224175935_Init.cs
-a----       24.12.2019     18:59          46048 20191224175935_Init.Designer.cs
-a----       24.12.2019     18:59          46010 MigrationEFCoreDbContextModelSnapshot.cs

Update Migration - and DevOps

You can run your migration changes with following command:

dotnet ef database update

To specify a migration, you can pass the name or the signature of your migration:

dotnet ef database update Init // or
dotnet ef database update 20191219180921_Init

Hint: the database connection string must be part of the migration project application settings. Those settings can also be part of your devops projects like environment variables!

A lot of people export the migrations as script (dotnet ef migrations script) and use a DACPAC file for database DevOps.

Remove Migration

To remove the latest migration you can use

dotnet ef migrations remove

References

See also: EFCore Migrations - Microsoft Docs