Closed Danielku15 closed 10 months ago
Standalone project for testing.
Just run dotnet ef migrations add Test2 --project EFCore-Issue27502
and the exception appears.
EFCore-Issue27502.zip
Note for triage: verified that this works when the runtime service is replaced instead of the design-time service. We should document better when to replace a runtime verses design-time service.
Docs covered by https://github.com/dotnet/EntityFramework.Docs/issues/4013
@ajcvickers Sorry to revive this closed issue. What is your proposed solution to this problem? I just faced this problem again. We have a custom IDesignTimeServices
registering a custom IMigrationsIdGenerator
. Running the dotnet ef migraitons add
fails within the built-in generator not using ours. Still happening in .net 8.
@Danielku15 Use ReplaceService
when building the DbContext
options. This service is used at runtime as well as at design time, so it needs to replaced in the runtime configuration.
Thanks a lot for the quick help. Got it running. Took a bit of code to reuse my current IDesignTimeServices
also during runtime without negative impact but works good for my needs.
For future readers:
IDesignTimeDbContextFactory<T>
and register it in IDesignTimeServices.ConfigureDesignTimeServices
for my DB context.IDbContextOptionsExtension
which I add to my options in IDesignTimeDbContextFactory
. IDbContextOptionsExtension.ApplyServices
I call over to IDesignTimeServices.ConfigureDesignTimeServices
Maybe there is a nicer (built-in) way to tell a DB context to also load and register the IDesignTimeServices but I'm fine for now doing this on my own.
Disclaimer: We only do migrations manually via dotnet ef migrations
and not by using the design time services and context in our code. There might be side effects in other toolings or design time services.
I am having a custom
IMigrationsIdGenerator
implementation which rather uses an incremented version number over the timestamp. Generally it is working fine, but I just came to notice that in case the migration name is too short, anArgumentOutOfRange
exception is thrown because my id generator is not used in all scenarios and the default implementation expects a minimum length and some other format.I digged a bit deeper and found out that there might be a dependency issue that for some classes the
IMigrationsIdGenerator
is created too early and later not taken from the custom design time services.Steps to reproduce
dotnet ef migrations add Test
(leading to a 001_Test migration)CustomDesignTimeServices.cs
```cs using System.Diagnostics; using System.Text.RegularExpressions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Design; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations.Design; using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.Extensions.DependencyInjection.Extensions; [assembly: DesignTimeServicesReference("MyProject.CustomDesignTimeServices, MyProject")] namespace MyProject; public sealed class CustomDesignTimeServices : IDesignTimeServices { ///Insights on where the problem is caused
The default ID generator is created as part of this callstack:
https://github.com/dotnet/efcore/blob/c1eeaff2c3c431343b691164c424d99cf89a2ec0/src/EFCore.Design/Design/Internal/MigrationsOperations.cs#L87
The custom ID generator is created as part of this callstack (which is a few lines after the callstack above):
https://github.com/dotnet/efcore/blob/c1eeaff2c3c431343b691164c424d99cf89a2ec0/src/EFCore.Design/Design/Internal/MigrationsOperations.cs#L91
I'm not yet sure how a fix could look like, but at the end the correct IMigrationsIdGenerator needs to be used when calling the following method. https://github.com/dotnet/efcore/blob/c1eeaff2c3c431343b691164c424d99cf89a2ec0/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs#L71
Include provider and version information
EF Core version: 6.0.1 Database provider Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 6.0 Operating system: Windows 11 Enterprise 21H2 22000.493 IDE: dotnet CLI for this case.