Pomelo.entityframeworkcore.mysql: El andamiaje de la base de datos produce un código incorrecto cuando las tablas tienen columnas de fecha y hora / marca de tiempo con el valor predeterminado CURRENT_TIMESTAMP

Creado en 31 oct. 2018  ·  3Comentarios  ·  Fuente: PomeloFoundation/Pomelo.EntityFrameworkCore.MySql

pasos para reproducir

Crea una tabla como esta:

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)
);

correr:

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

La cuestión

Pomelo establece el valor predeterminado 'CURRENT_TIMESTAMP' (cadena) en lugar de CURRENT_TIMESTAMP

El código generado es:
`` c #
anulación protegida void OnModelCreating (ModelBuilder modelBuilder)
{
modelBuilder.Entity(entidad =>
{
entidad.Propiedad (e => e.Dt)
.HasDefaultValueSql ("'CURRENT_TIMESTAMP'") // <- problema
.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:

información: Microsoft.EntityFrameworkCore.Infrastructure [10403]
Entity Framework Core 2.1.2-rtm-30932 inicializó 'TestDb' usando el proveedor 'Pomelo.EntityFrameworkCore.MySql' con opciones: Ninguna
información: Microsoft.EntityFrameworkCore.Database.Command [20101]
DbCommand ejecutado (3ms) [Parameters = [], CommandType = 'Text', CommandTimeout = '30 ']
CREAR BASE DE DATOS TestDb_EFCore ;
falla: Microsoft.EntityFrameworkCore.Database.Command [20102]
Error al ejecutar DbCommand (1ms) [Parameters = [], CommandType = 'Text', CommandTimeout = '30 ']
CREAR TABLA TimestampTable (
Id int (11) AUTO_INCREMENT NO NULL,
Ts marca
Dt datetime NULL DEFAULT 'CURRENT_TIMESTAMP',
RESTRICCIÓN PK_TimestampTable LLAVE PRIMARIA ( Id )
);

Exception message:

MySql.Data.MySqlClient.MySqlException (0x80004005): valor predeterminado no válido para 'Ts'

Stack trace:

MySql.Data.MySqlClient.MySqlException (0x80004005): valor predeterminado no válido para 'Ts' ---> MySql.Data.MySqlClient.MySqlException (0x80004005): valor predeterminado no válido para 'Ts'
en MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync (IOBehavior ioBehavior) en C: \ projects \ mysqlconnector \ src \ MySqlConnector \ Core \ ResultSet.cs: línea 42
en MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet (ResultSet resultSet) en C: \ proyectos \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient \ MySqlDataReader.cs: línea 74
en MySql.Data.MySqlClient.MySqlDataReader.ReadFirstResultSetAsync (IOBehavior ioBehavior) en C: \ projects \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient \ MySqlData:
en MySql.Data.MySqlClient.MySqlDataReader.CreateAsync (comando MySqlCommand, comportamiento CommandBehavior, ResultSetProtocol resultSetProtocol, IOBehavior ioBehavior) en C: \ projects \ mysqlconnector \ src \ MySqlConneq
en MySqlConnector.Core.TextCommandExecutor.ExecuteReaderAsync (String commandText, MySqlParameterCollection parameterCollection, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) en C: \ proyectos \ mysqlconnector \ src \ MySql.
en MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQueryAsync (IOBehavior ioBehavior, CancellationToken cancellationToken) en C: \ projects \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient 26
en MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery () en C: \ proyectos \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient \ MySqlCommand.cs: línea 62
en Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute (conexión IRelationalConnection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)

Excepción no controlada: MySql.Data.MySqlClient.MySqlException: valor predeterminado no válido para 'Ts' ---> MySql.Data.MySqlClient.MySqlException: valor predeterminado no válido para 'Ts'
en MySqlConnector.Core.ResultSet.ReadResultSetHeaderAsync (IOBehavior ioBehavior) en C: \ projects \ mysqlconnector \ src \ MySqlConnector \ Core \ ResultSet.cs: línea 42
--- Fin del seguimiento de la pila de excepciones internas ---
en MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet (ResultSet resultSet) en C: \ proyectos \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient \ MySqlDataReader.cs: línea 74
en MySql.Data.MySqlClient.MySqlDataReader.ReadFirstResultSetAsync (IOBehavior ioBehavior) en C: \ projects \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient \ MySqlData:
en MySql.Data.MySqlClient.MySqlDataReader.CreateAsync (comando MySqlCommand, comportamiento CommandBehavior, ResultSetProtocol resultSetProtocol, IOBehavior ioBehavior) en C: \ projects \ mysqlconnector \ src \ MySqlConneq
en MySqlConnector.Core.TextCommandExecutor.ExecuteReaderAsync (String commandText, MySqlParameterCollection parameterCollection, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) en C: \ proyectos \ mysqlconnector \ src \ MySql.
en MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQueryAsync (IOBehavior ioBehavior, CancellationToken cancellationToken) en C: \ projects \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient 26
en MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery () en C: \ proyectos \ mysqlconnector \ src \ MySqlConnector \ MySql.Data.MySqlClient \ MySqlCommand.cs: línea 62
en Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute (conexión IRelationalConnection, DbCommandMethod executeMethod, IReadOnlyDictionary 2 parameterValues) at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary 2 parameterValues)
en Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery (IEnumerable`1 migrationCommands, conexión IRelationalConnection)
en Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreated ()
en CreateDb.Program.Main (String [] args) en /git/netcore-planet-garavot8-data/CreateDb/Program.cs:line 30
''

Más detalles técnicos

Versión de MySQL: 5.7.20
Sistema operativo: CentOS 7.4
Pomelo.EntityFrameworkCore.MySql versión: 2.1.2

type-bug

Comentario más útil

La lógica de los valores predeterminados en la clase MySqlDatabaseModelFactory es actualmente rudimentaria, ya que asume que el valor predeterminado es una cadena.

Se requerirá la verificación de tipo, es decir, varchar, int, enum, etc. para determinar si se requieren comillas (y usar el escape si es necesario) y también seguir las reglas en los valores predeterminados del tipo de datos .

Todos 3 comentarios

La lógica de los valores predeterminados en la clase MySqlDatabaseModelFactory es actualmente rudimentaria, ya que asume que el valor predeterminado es una cadena.

Se requerirá la verificación de tipo, es decir, varchar, int, enum, etc. para determinar si se requieren comillas (y usar el escape si es necesario) y también seguir las reglas en los valores predeterminados del tipo de datos .

Corregido en # 896.

Encuentro que los códigos a continuación pueden funcionar bien y evitar el error antes del lanzamiento de la nueva versión.
`` C #
anulación protegida void OnModelCreating (ModelBuilder modelBuilder)
{
modelBuilder.Entity(entidad =>
{
entidad.Propiedad (e => e.Dt)
.HasDefaultValueSql ("CURRENT_TIMESTAMP ()")
.ValueGeneratedOnAddOrUpdate ();

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

''

¿Fue útil esta página
0 / 5 - 0 calificaciones