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

Migration not applying after upgrading to .NET 5 #1600

Closed
danielbecroft opened this issue Dec 7, 2020 · 7 comments · Fixed by cmu-sei/Caster.Api#37
Closed

Migration not applying after upgrading to .NET 5 #1600

danielbecroft opened this issue Dec 7, 2020 · 7 comments · Fixed by cmu-sei/Caster.Api#37

Comments

@danielbecroft
Copy link

We have an application that was started under .NET Core 3.0, and has had a number of migrations generated and applied.

For some of our models, we added "shadow properties" like the below, that we added for automatic tracking of auditing and the like. One of the example fields is the CreatedOn field:

protected override void OnModelCreating(ModelBuilder builder)
{
    builder.Entity<Post>().Property<DateTime>("CreatedOn").HasDefaultValueSql("now()");
}

After adding this field, we changed this from DateTime to DateTimeOffset, and the migration was generated as:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<DateTimeOffset>(
        name: "CreatedOn",
        table: "Posts",
        nullable: false,
        defaultValueSql: "now()",
        oldClrType: typeof(DateTime),
        oldDefaultValueSql: "now()");
}

This migration correctly applies under .NET Core 3.1. However, when running the migration under .NET 5, the statement is a no-op. The migration is recorded as run during the .Migrate() phase, but nothing else happens. The datatype of the field is not changed.

NOTE: This matches the committed version of our migration. Attempting to replicate this issue, the migration includes an oldType: "timestamp without time zone" line. If I include this line, both versions correctly apply the migration. Removing this line causes .NET 5 to not apply the migration, but .NET Core 3.1 does.

Running dotnet ef migrations script between the two migrations gives the following:

.NET Core 3.1

ALTER TABLE "Posts" ALTER COLUMN "CreatedOn" TYPE timestamp with time zone;
ALTER TABLE "Posts" ALTER COLUMN "CreatedOn" SET NOT NULL;
ALTER TABLE "Posts" ALTER COLUMN "CreatedOn" SET DEFAULT (now());

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20201207050840_ChangeCreatedOnPropertyToDateTimeOffset', '3.0.0');

.NET 5

START TRANSACTION;

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20201207050840_ChangeCreatedOnPropertyToDateTimeOffset', '5.0.0');

COMMIT;

Was there a fix where a previous version would not include the oldType line in the migration? (trying to work out why this line would not have been included in the original migration)?
Is this a bug where we have a migration that no longer applies between the major versions?

I've setup a basic repository with the example migrations here.

@AmadeoDecay

This comment has been minimized.

@roji

This comment has been minimized.

@AmadeoDecay

This comment has been minimized.

@roji

This comment has been minimized.

@roji
Copy link
Member

roji commented Feb 22, 2021

@danielbecroft sorry for not commenting on this sooner...

I've tried generating migrations with EF Core 5.0, 3.1 and 3.0:

EF Core 3.0
protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<DateTimeOffset>(
        name: "CreatedOn",
        table: "Blogs",
        nullable: false,
        defaultValueSql: "now()",
        oldClrType: typeof(DateTime),
        oldType: "timestamp without time zone",
        oldDefaultValueSql: "now()");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<DateTime>(
        name: "CreatedOn",
        table: "Blogs",
        type: "timestamp without time zone",
        nullable: false,
        defaultValueSql: "now()",
        oldClrType: typeof(DateTimeOffset),
        oldDefaultValueSql: "now()");
}
EF Core 3.1
protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<DateTimeOffset>(
        name: "CreatedOn",
        table: "Blogs",
        nullable: false,
        defaultValueSql: "now()",
        oldClrType: typeof(DateTime),
        oldType: "timestamp without time zone",
        oldDefaultValueSql: "now()");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<DateTime>(
        name: "CreatedOn",
        table: "Blogs",
        type: "timestamp without time zone",
        nullable: false,
        defaultValueSql: "now()",
        oldClrType: typeof(DateTimeOffset),
        oldDefaultValueSql: "now()");
}
EF Core 5.0
protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<DateTimeOffset>(
        name: "CreatedOn",
        table: "Blogs",
        type: "timestamp with time zone",
        nullable: false,
        defaultValueSql: "now()",
        oldClrType: typeof(DateTime),
        oldType: "timestamp without time zone",
        oldDefaultValueSql: "now()");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<DateTime>(
        name: "CreatedOn",
        table: "Blogs",
        type: "timestamp without time zone",
        nullable: false,
        defaultValueSql: "now()",
        oldClrType: typeof(DateTimeOffset),
        oldType: "timestamp with time zone",
        oldDefaultValueSql: "now()");
}

I can consistently see oldType in the Up migrations, but it's indeed missing in the Down migration generated for EF Core 3.1. Your code fragment above shows an Up migration - is it possible that this is a migration generated before EF Core 3.0?

@danielbecroft
Copy link
Author

Hi @roji ,
These migrations were created under EF Core 3 (I can't recall if they were 3.0 or 3.1).

@roji
Copy link
Member

roji commented Mar 10, 2021

Closing as per #1663 (comment)

@roji roji closed this as completed Mar 10, 2021
sei-aschlackman added a commit to cmu-sei/Caster.Api that referenced this issue Jan 20, 2022
- added types to migrations to fix npgsql/efcore.pg#1600
- updated to latest npgsql
- added null cheks to seed data processing
sei-aschlackman added a commit to cmu-sei/Caster.Api that referenced this issue Jan 20, 2022
…le (#37)

- added types to migrations to fix npgsql/efcore.pg#1600
- updated to latest npgsql
- added null cheks to seed data processing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants