Search code examples
c#mysqlentity-frameworkef-code-first

EF6 with MySQL - formatexception in datetime


I have DB coded like this:

public class DBModel : DbContext
    {
        public DBModel()
            : base("name=DBModel")
        {
        }

        public virtual DbSet<Entry> Entries{ get; set; }
    }

    public class Entry
    {
        [Key]
        public int Id { get; set; }
        public DateTime EntryDate { get; set; }
        public string EntryContent { get; set; }
        public virtual Alarm Alarm { get; set; }
    }

    public class Alarm
    {
        [Key]
        public int AlarmId { get; set; }
        public DateTime AlarmDate { get; set; }
        public bool Enabled { get; set; }
    }

when I'm trying to update Database, it ends with FormatException with this stack:

System.FormatException: Nieprawidłowy format ciągu wejściowego.
   w System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
   w System.Convert.ToDouble(String value)
   w MySql.Data.Entity.MySqlMigrationSqlGenerator.Generate(CreateIndexOperation op)
   w MySql.Data.Entity.MySqlMigrationSqlGenerator.Generate(IEnumerable`1 migrationOperations, String providerManifestToken)
   w System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
   w System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
   w System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.AutoMigrate(String migrationId, VersionedModel sourceModel, VersionedModel targetModel, Boolean downgrading)
   w System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   w System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   w System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
   w System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   w System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   w System.Data.Entity.Infrastructure.Design.Executor.Update.<>c__DisplayClass0_0.<.ctor>b__0()
   w System.Data.Entity.Infrastructure.Design.Executor.OperationBase.Execute(Action action)

EF framework version: 6.4.4 MySQL server version: 8.0.18 MySQL plugins:

  • MySQL.Data v6.10.9
  • MySQL.Data v6.10.9

How to fix it?


Solution

  • This looks like a bug in MySql.Data.EntityFramework, caused by this line: https://github.com/mysql/mysql-connector-net/blob/f3b6ae6a416de898b25edc0062b25a2f6ea90291/EntityFramework/src/MySqlMigrationSqlGenerator.cs#L771

    I'm guessing that _providerManifestToken contains a string like "8.0", but your program is running in a locale (pl-PL?) where floating-point numbers are formatted like 8,0. Thus the culture-sensitive call to Convert.ToDouble fails.

    You could report this as a bug at https://bugs.mysql.com and wait for a fix.

    Alternatively, it may be possible to set Thread.CurrentCulture to en-US to run the migration (Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");) then set it back afterwards.