Closed snebjorn closed 2 months ago
Duplicate of #2962
See other issues referenced from #2962 which also discuss this.
That's unfortunate.
I don't know the inner workings of EF. But this comment
this is by-design. Types that the provider handles natively are considered to be stable, and we can't think of any better rule than this.
got me wondering if it is possible for the Npgsql provider to supply its own stable enum type and then use value converters - or something like that
Perhaps the migration can look like this
table.Column<NpgsqlEnumType>( // references the stable provider enum type
type: "mood", // this is the actual enum type
nullable: false,
defaultValue: "thrilled" // just a string here
)
The problem is that if you add a value converter, that's also going to get used e.g. when sending enum parameters to the database, in queries and updates. There's no concept of one type used only for migrations (e.g. NpgsqlEnumType), and another used for the rest.
It really is an unfortunate and tricky problem. On the other hand, people have seemed to generally be OK to keep the enum types around in the codebase, and to remove them only when squashing the migrations, removing all trace/reference of them. It's definitely not perfect, but not completely terrible either.
Using the actual enum type in migrations is problematic - I'll explain
Given this model
Generate our initial migration and apply it to the database.
Now remove
[PgName("thrilled")]
fromMood
. Write the next migration and apply it to the database.Up to this point everything have worked.
Now drop the database and run the migrations.
An exception will be thrown saying:
This happens because we first run the initial migration (mentioned above) which have
defaultValue: Mood.Happy
which used to bedefaultValue: "thrilled"
when it was generated and ran the first time. But now Mood.Happy is "happy" which isn't a valid value.The SQL is probably easier to reason about
Will look like this
The problem isn't just with the default value. Since the migration references the actual enum type that enum can never be deleted else it'll cause compile errors. This is a bit critical 😄
I was using: