Efcore.pg: Add second enum (ForNpgsqlHasEnum) causes error

Created on 14 Aug 2019  路  4Comments  路  Source: npgsql/efcore.pg

This seems to be a regression of 528.

I'm using:

  • Npgsql: 4.0.7
  • Npgsql.EntityFrameworkCore.PostgreSQL 2.2.4
  • Microsoft.EntityFrameworkCore 2.2.6

As mentioned in 528...

I have an existing Enum (myEnum1) which is deployed to DB.
I add a new Enum (myEnum2).
I run dotnet ef migrations add mySecondMigration
I run dotnet ef migrations script and get error message (below)
I can see the following in the migration script:

migrationBuilder.AlterDatabase()
.Annotation("Npgsql:Enum:myEnum1", "New,Submitted,Failed,AwaitingCapture")
.Annotation("Npgsql:Enum:myEnum2", "New,Submitted,Failed")
.OldAnnotation("Npgsql:Enum:myEnum1", "New,Submitted,Failed,AwaitingCapture");
````

Error message:

System.NotSupportedException: Altering enum type $Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.PostgresEnum isn't supported.
at Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.NpgsqlMigrationsSqlGenerator.GenerateEnumStatements(AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) in C:\projectsnpgsql-entityframeworkcore-postgresql\src\EFCore.PG\Migrations\NpgsqlMigrationsSqlGenerator.cs:line 704
at Npgsql.EntityFrameworkCore.PostgreSQL.Migrations.NpgsqlMigrationsSqlGenerator.Generate(AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) in C:\projectsnpgsql-entityframeworkcore-postgresql\src\EFCore.PG\Migrations\NpgsqlMigrationsSqlGenerator.cs:line 646
at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
at Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGenerator.Generate(IReadOnlyList1 operations, IModel model) at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.GenerateUpSql(Migration migration) at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.GenerateScript(String fromMigration, String toMigration, Boolean idempotent) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.ScriptMigration(String fromMigration, String toMigration, Boolean idempotent, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_01.b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
```

bug

Most helpful comment

I'm having this issue in 2.2.4 any chance we could get this backported?

Also it would be nice if you allowed altering enums, adding new values or renaming the entire enum.

All 4 comments

Still happening for me with version 3.0.1

I'm having this issue in 2.2.4 any chance we could get this backported?

Also it would be nice if you allowed altering enums, adding new values or renaming the entire enum.

This still appears to be an issue in 3.1.0.

@apshoemaker, @vsvirydau-cl or someone else, could you please open a new issue with clear instructions on how to reproduce the problem?

Trying to do the following works well:

```c#
class Program
{
static void Main()
{
using var ctx = new BlogContext();
ctx.Database.EnsureDeleted();
ctx.Database.EnsureCreated();
}
}

public class BlogContext : DbContext
{
public DbSet Blogs { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder.UseNpgsql("...");

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasPostgresEnum<Enum1>();
    // modelBuilder.HasPostgresEnum<Enum2>();  // Uncomment only for second migration
}

}

public enum Enum1
{
Value1,
Value2
};

public enum Enum2
{
Value3,
Value4
};

public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
public List Posts { get; set; }
}

public class Post
{
public int Id { get; set; }
public string Title { get; set; }
}


Steps:

1. Generate first initial migration (one enum in model)
2. Uncomment the line above, adding the second enum to the model
3. Generating the second migration
4. Generate a migration script (`dotnet ef migrations script`).

The result works well and at the end I have both enums in the database:

```sql
CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" (
    "MigrationId" character varying(150) NOT NULL,
    "ProductVersion" character varying(32) NOT NULL,
    CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId")
);

CREATE TYPE enum1 AS ENUM ('value1', 'value2');

CREATE TABLE "Blogs" (
    "Id" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    "Name" text NULL,
    CONSTRAINT "PK_Blogs" PRIMARY KEY ("Id")
);

CREATE TABLE "Post" (
    "Id" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    "Title" text NULL,
    "BlogId" integer NULL,
    CONSTRAINT "PK_Post" PRIMARY KEY ("Id"),
    CONSTRAINT "FK_Post_Blogs_BlogId" FOREIGN KEY ("BlogId") REFERENCES "Blogs" ("Id") ON DELETE RESTRICT
);

CREATE INDEX "IX_Post_BlogId" ON "Post" ("BlogId");

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20200123161609_initial', '3.1.1');

CREATE TYPE enum2 AS ENUM ('value3', 'value4');

INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
VALUES ('20200123161621_second', '3.1.1');
Was this page helpful?
0 / 5 - 0 ratings