Open GunnerGuyven opened 1 year ago
Hi @GunnerGuyven So Migration 4 is failing even though it has no changes compared to 3? So 4 should just be an empty migration?
Sounds like it could be related to Pomelo if it works with Microsoft.EntityFrameworkCore.Sqlite
, I notice the stacktrace doesn't mention this projects override of the ModelDiffer
, EntityFrameworkCore.FSharp.Migrations.Internal. FSharpMigrationsModelDiffer
@bricelam, quick question, in IDesignTimeServices.ConfigureDesignTimeServices
we call services.AddSingleton<IMigrationsModelDiffer, FSharpMigrationsModelDiffer>()
If the Pomelo Sqlite connector also overrides IMigrationsModelDiffer
would EF just pick up whichever one was registered last?
That's right, there is no model change. I have narrowed this issue to the presence of the option type itself in the previous migration. You can construct an elaborate model involving option types and so long as there are no previous migrations (involving option types), the migration will succeed.
I have created a project demonstrating this issue
git clone https://github.com/GunnerGuyven/ef-pomelo-fsharp-migrate-failure
cd .\ef-pomelo-fsharp-migrate-failure\
dotnet tool restore
dotnet restore
dotnet ef migrations add test4
And opened a ticket with Pomelo to match this one (https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/issues/1700)
@simon-reynolds Researching the codebase of Pomelo, I see that they do indeed also add an IMigrationsModelDiffer
to the EF builder. This seems done to handle some MySql specific peculiarities with datetime
and timestamp
fields in certain situations. Surely there is a way of navigating when two handlers have been registered in this manner by different stakeholders?
If there is a 'good citizen' approach to this problem, what would it be and which library should hold that responsibility?
bricelam, quick question, in IDesignTimeServices.ConfigureDesignTimeServices we call services.AddSingleton<IMigrationsModelDiffer, FSharpMigrationsModelDiffer>() If the Pomelo Sqlite connector also overrides IMigrationsModelDiffer would EF just pick up whichever one was registered last?
The model differ is not designed to be overridden by providers or extensions. Additional functionality should instead be enabled using model annotations.
This seems done to handle some MySql specific peculiarities with datetime and timestamp fields in certain situations.
I vaguely remember this. I think there's an EF issue to review this code and see if there's anything we can add to make this better.
What functionality is currently added by the F# override? Could it be part of the core EF implementation?
The F# override is to add support for the Option<_>
type, it's a wrapper similar to Nullable<_>
F# tries to avoid use of null
as much as possible, so it uses the option type instead that wraps an item that may or may not be capable of having a null value
The F# model differ matches conventions by marking every column that isn't a PrimaryKey as non-nullable unless the CLR type is either Nullable<_>
or Option<_>
Since Option<_>
is F# specific, I don't know if there's appetite in EF Core for including it?
Hmm, it feels like this shouldn't be needed in the differ. An F#-specific model building convention should mark the IColumn as IsNullable when the CLR type uses option
.
/cc @AndriySvyryd
Describe the bug A migration cannot be created when using
Pomelo.EntityFrameworkCore.MySql
as the connector when an option type is present on the existing (pre-migration) model.To Reproduce Starting with the following model:
No Database is necessary, this issue is only concerned with creating migrations. Steps to reproduce the behavior:
dotnet ef migrations add test1
(no issue)dotnet ef migrations add test2
(no issue)dotnet ef migrations add test3
(no issue)dotnet ef migrations add test4
(FAIL)Expected behavior I would expect migration 4 to succeed.
Additional context This works with
Microsoft.EntityFrameworkCore.Sqlite
so it may be a failure of the Pomelo connector specifically, but I am unsure. I've tested all of the 6.0.x releases of Pomelo's connector with the same result.