EF Core database update specify base version

3

In my projects I have two EF core migrations files in the Migrations folder which I have created based on the initial release and after an update. The initial migration ("Initial") contains many CreateTable statements, whereas the second migration ("Cleanup") only contains a few DropColumn statements in their Up methods.

My database was created by a call to context.Database.EnsureCreated() between the first and the second migration, i.e. I would now like to execute the second migration. However, if I call dotnet ef database update Cleanup I receive an error:

Applying migration '20190409043916_Initial'.
Failed executing DbCommand (6ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CREATE TABLE [LongRunningOperations] (
    [Id] bigint NOT NULL IDENTITY,
    [Start] datetime2 NOT NULL,
    [End] datetime2 NULL,
    [Discriminator] nvarchar(max) NOT NULL,
    CONSTRAINT [PK_LongRunningOperations] PRIMARY KEY ([Id])
);
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'LongRunningOperations' in the database.

Obviously, EF wants to apply the first migration as well. Is there an option to specify the base version of the database? Can I do something else to avoid that the "Initial" migration is executed?

A more general question that might help me understand what's happening: How does EF Core determine what the base version is, i.e. which migrations must be executed?

c#
entity-framework-core
ef-migrations
asked on Stack Overflow Apr 10, 2019 by Philipp

1 Answer

2

My database was created by a call to context.Database.EnsureCreated()

That's the root of the problem. The documentation for Create and Drop APIs contains the following:

Warning

EnsureCreated and Migrations don't work well together. If you're using Migrations, don't use EnsureCreated to initialize the schema.

and then:

Transitioning from EnsureCreated to Migrations is not a seamless experience. The simplest way to do it is to drop the database and re-create it using Migrations. If you anticipate using migrations in the future, it's best to just start with Migrations instead of using EnsureCreated.

Similar in Apply migrations at runtime:

Warning

  • Don't call EnsureCreated() before Migrate(). EnsureCreated() bypasses Migrations to create the schema, which causes Migrate() to fail.

Shortly, you should have used either EF Core tools or context.Database.Migrate() for creating/updating database.

Since you did it the wrong way, either follow their recommendation to "drop the database and re-create it using Migrations", or try to reconstruct the Migrations History Table the way EF Core would have created and populated it initially if you were using the intended migrations workflow.

answered on Stack Overflow Apr 10, 2019 by Ivan Stoev

User contributions licensed under CC BY-SA 3.0