ef core using system calendar format for generating migration names.
example of standard migration name for the Gregorian calendar on windows:
20190206144020_MIGRATION-NAME
But if the date format of Windows is something other than the Gregorian, like Persian calendar the ef core migration name generates something like :
13971114210223_MIGRATION-NAME
in a team project, we cannot use both formats because it's changing the order of migrations.
is there any way to fix that issue without changing windows calendar format or manually rename the migration?
version: EF core 2.2
This is simply a bug in the MigrationsIdGenerator class for the latest at this time EF Core 2.2.4 - in the last line of GenerateId
method:
return timestamp.ToString(Format) + "_" + name;
they simply forgot to pass CultureInfo.InvariantCulture
to DateTime.Format
method.
It's already fixed in the current code (I believe for EF Core 3.0), so you either wait for it, or copy/paste the current code to your project (rename the class to let say FixedMigrationsIdGenerator
) and then inside your DbContext
derived class, override OnConfiguring
and add the following (with the necessary using
s):
optionsBuilder.ReplaceService<IMigrationsIdGenerator, FixedMigrationsIdGenerator>();
I've extended the accepted answer and created a class derived from the MigrationsIdGenerator
class overriding only the GenerateId
method:
public class FixedMigrationsIdGenerator : MigrationsIdGenerator
{
private const string Format = "yyyyMMddHHmmss";
private DateTime _lastTimestamp = DateTime.MinValue;
private readonly object _lock = new object();
public override string GenerateId(string name)
{
var now = DateTime.UtcNow;
var timestamp = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
lock (_lock)
{
if (timestamp <= _lastTimestamp)
{
timestamp = _lastTimestamp.AddSeconds(1);
}
_lastTimestamp = timestamp;
}
return timestamp.ToString(Format, CultureInfo.InvariantCulture) + "_" + name;
}
}