Pomelo.entityframeworkcore.mysql: L'échafaudage de base de données produit un code erroné lorsque les tables ont des colonnes datetime/timestamp avec la valeur par défaut CURRENT_TIMESTAMP

Créé le 31 oct. 2018  ·  3Commentaires  ·  Source: PomeloFoundation/Pomelo.EntityFrameworkCore.MySql

Étapes à reproduire

Créez un tableau comme celui-ci :

create table TimestampTable(
    Id int not null,
    Ts timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
    Dt datetime default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
    primary key (Id)
);

Cours:

dotnet ef dbcontext scaffold \
    --data-annotations \
    --context TestDb \
    --force \
    --use-database-names \
    "my_connection_string" \
    "Pomelo.EntityFrameworkCore.MySql"

Le problème

Pomelo définit la valeur par défaut 'CURRENT_TIMESTAMP' (chaîne) au lieu de CURRENT_TIMESTAMP

Le code généré est :
```c#
remplacement protégé void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(entité =>
{
entity.Property(e => e.Dt)
.HasDefaultValueSql("'CURRENT_TIMESTAMP'") // <-- problème
.ValueGeneratedOnAddOrUpdate();

            entity.Property(e => e.Ts)
                .HasDefaultValueSql("'CURRENT_TIMESTAMP'") // <-- problem
                .ValueGeneratedOnAddOrUpdate();
        });
    }
Trying to recreate the database with `myDbContext.Database.EnsureCreated()` will throw an exception 
because the default value for the `timestamp` column is `'CURRENT_TIMESTAMP'`.

EFCore Log:

info : Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 2.1.2-rtm-30932 a initialisé « TestDb » à l'aide du fournisseur « Pomelo.EntityFrameworkCore.MySql » avec les options : aucune
info : Microsoft.EntityFrameworkCore.Database.Command[20101]
Exécuté DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CRÉER UNE BASE DE DONNÉES TestDb_EFCore ;
échec : Microsoft.EntityFrameworkCore.Database.Command[20102]
Échec de l'exécution de DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
CRÉER TABLE TimestampTable (
Id int(11) NON NULL AUTO_INCREMENT,
Ts horodatage NON NULL PAR DÉFAUT 'CURRENT_TIMESTAMP',
Dt datetime NULL DEFAULT 'CURRENT_TIMESTAMP',
CONTRAINTE PK_TimestampTable CLÉ PRIMAIRE ( Id )
);

Exception message:

MySql.Data.MySqlClient.MySqlException (0x80004005) : valeur par défaut non valide pour 'Ts'

Stack trace:

MySql.Data.MySqlClient.MySqlException (0x80004005) : valeur par défaut non valide pour 'Ts' ---> MySql.Data.MySqlClient.MySqlException (0x80004005) : valeur par défaut non valide pour 'Ts'
à MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) dans C:\projects\mysqlconnector\src\MySqlConnector\Core\ResultSet.cs:line 42
à MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet(ResultSet resultSet) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 74
à MySql.Data.MySqlClient.MySqlDataReader.ReadFirstResultSetAsync(IOBehavior ioBehavior) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 299
à MySql.Data.MySqlClient.MySqlDataReader.CreateAsync (commande MySqlCommand, comportement CommandBehavior, ResultSetProtocol resultSetProtocol, IOBehavior ioBehavior) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Clientline.84
à MySqlConnector.Core.TextCommandExecutor.ExecuteReaderAsync (String commandText, MySqlParameterCollection parameterCollection, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancelToken) dans C:\projects\mysqlconnector\csrc\MyTextCommand\Core\.ecutor
à MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancelToken) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 261
à MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 62
à Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute (connexion IRelationalConnection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)

Exception non gérée : MySql.Data.MySqlClient.MySqlException : valeur par défaut non valide pour 'Ts' ---> MySql.Data.MySqlClient.MySqlException : valeur par défaut non valide pour 'Ts'
à MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync(IOBehavior ioBehavior) dans C:\projects\mysqlconnector\src\MySqlConnector\Core\ResultSet.cs:line 42
--- Fin de la trace de la pile d'exception interne ---
à MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet(ResultSet resultSet) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 74
à MySql.Data.MySqlClient.MySqlDataReader.ReadFirstResultSetAsync(IOBehavior ioBehavior) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 299
à MySql.Data.MySqlClient.MySqlDataReader.CreateAsync (commande MySqlCommand, comportement CommandBehavior, ResultSetProtocol resultSetProtocol, IOBehavior ioBehavior) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Clientline.84
à MySqlConnector.Core.TextCommandExecutor.ExecuteReaderAsync (String commandText, MySqlParameterCollection parameterCollection, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancelToken) dans C:\projects\mysqlconnector\csrc\MyTextCommand\Core\.ecutor
à MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQueryAsync(IOBehavior ioBehavior, CancellationToken cancelToken) dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 261
à MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery() dans C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 62
à Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute (connexion IRelationalConnection, DbCommandMethod executeMethod, IReadOnlyDictionary 2 parameterValues) at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary 2 parametersValues)
à Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, connexion IRelationalConnection)
à Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreated()
à CreateDb.Program.Main(String[] args) dans /git/netcore-planet-garavot8-data/CreateDb/Program.cs:line 30
```

Plus de détails techniques

Version MySQL : 5.7.20
Système d'exploitation : CentOS 7.4
Version Pomelo.EntityFrameworkCore.MySql : 2.1.2

type-bug

Commentaire le plus utile

La logique des valeurs par défaut dans la classe MySqlDatabaseModelFactory est actuellement rudimentaire car elle suppose que la valeur par défaut est une chaîne.

La vérification de type sera nécessaire, à savoir varchar, int, etc. ENUM pour déterminer si les guillemets sont nécessaires (et d'utiliser le cas échéant échapper) , ainsi que les règles suivantes dans Type de

Tous les 3 commentaires

La logique des valeurs par défaut dans la classe MySqlDatabaseModelFactory est actuellement rudimentaire car elle suppose que la valeur par défaut est une chaîne.

La vérification de type sera nécessaire, à savoir varchar, int, etc. ENUM pour déterminer si les guillemets sont nécessaires (et d'utiliser le cas échéant échapper) , ainsi que les règles suivantes dans Type de

Corrigé dans #896.

Je trouve que les codes ci-dessous peuvent fonctionner correctement et éviter le bogue avant la sortie des nouvelles versions.
```C#
remplacement protégé void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(entité =>
{
entity.Property(e => e.Dt)
.HasDefaultValueSql("CURRENT_TIMESTAMP()")
.ValueGeneratedOnAddOrUpdate();

            entity.Property(e => e.Ts)
                .HasDefaultValueSql("CURRENT_TIMESTAMP()")
                .ValueGeneratedOnAddOrUpdate();
        });
    }

```

Cette page vous a été utile?
0 / 5 - 0 notes