Estoy tratando de cambiar el nombre de una columna a través de una migración en mi base de datos MySql.

Esta es mi migración:

public override void Up()
{
   //RenameColumn("Docks", "ProfileId", "SecondId"); <!-- doesn't work either
   RenameColumn("Docks", "ProfileId", "SecondId", anonymousArguments: new { ColumnType = "int" });
}

public override void Down()
{
   //RenameColumn("Docks", "SecondId", "ProfileId"); <!-- doesn't work either
   RenameColumn("Docks", "SecondId", "ProfileId", anonymousArguments:  new { ColumnType = "int" });
}

Cuando ejecuto Update-Database me arroja un gran error (si quieres ver el error completo, abre el fragmento), que incluye:

MySql.Data.MySqlClient.MySqlException (0x80004005): se debe definir el parámetro '@columnType'.

MySql.Data.MySqlClient.MySqlException(0x80004005): Fatal error encountered during command execution.-- - > MySql.Data.MySqlClient.MySqlException(0x80004005): Parameter '@columnType' must be defined. at MySql.Data.MySqlClient.Statement.SerializeParameter(MySqlParameterCollection
parameters, MySqlPacket packet, String parmName, Int32 parameterIndex) at MySql.Data.MySqlClient.Statement.InternalBindParameters(String sql, MySqlParameterCollection parameters, MySqlPacket packet) at MySql.Data.MySqlClient.Statement.BindParameters()
at MySql.Data.MySqlClient.PreparableStatement.Execute() at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.
< NonQuery> b__0(DbCommand t, DbCommandInterceptionContext `1 c) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher` 1. Dispatch[TTarget, TInterceptionContext, TResult](TTarget target, Func `3 operation, TInterceptionContext interceptionContext,
  Action` 3 executing, Action `3 executed) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext) at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery()
  at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(MigrationStatement
  migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable` 1 migrationStatements, DbConnection connection, DbTransaction
  transaction, DbInterceptionContext interceptionContext) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinTransaction(IEnumerable `1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinNewTransaction(IEnumerable`
  1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable `1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext)
  at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable` 1 migrationStatements, DbConnection connection) at System.Data.Entity.Migrations.DbMigrator.
  <> c__DisplayClass32.
    < ExecuteStatements> b__30() at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute(Action operation) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable `1 migrationStatements, DbTransaction existingTransaction) at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`
      1 migrationStatements) at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable `1 migrationStatements) at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel,
      IEnumerable` 1 operations, IEnumerable `1 systemOperations, Boolean downgrading, Boolean auto) at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration) at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration
      migration, DbMigration lastMigration) at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable` 1 pendingMigrations, String targetMigrationId, String lastMigrationId) at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable
      `1 pendingMigrations, String targetMigrationId, String lastMigrationId) at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration) at System.Data.Entity.Migrations.DbMigrator.
      <>c__DisplayClasse.
        <Update>b__d() at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) at System.Data.Entity.Migrations.DbMigrator.Update(String
          targetMigration) at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore() at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
          Fatal error encountered during command execution.

El modo detallado generó la siguiente consulta SQL antes de lanzar el error:

set @columnType := (select  case lower(IS_NULLABLE)
                            when 'no' then CONCAT(column_type, ' not null ')
                            when 'yes' then column_type end
    from  information_schema.columns
    where  table_name = 'Docks'
      and  column_name = 'ProfileId');
set @sqlstmt := (select concat('alter table `Docks`
                      change `ProfileId` `SecondId` ' , @columnType));
prepare stmt from @sqlstmt;
execute stmt;
deallocate prepare stmt;

Tenía curiosidad, así que copié y pegué el sql en el db y se ejecutó como se esperaba sin errores y renombré la columna con éxito con el tipo correcto de int(11).

Entonces, ¿cómo evito que se produzca este error a pesar de que está generando (aparentemente) un sql válido?


Editar: quería notar que la respuesta aceptada aquí funcionó para mí aunque no estaba usando dotconnect.

0
Zze 3 mar. 2018 a las 07:20

3 respuestas

La mejor respuesta

Solución encontrada del problema anterior: (MySql.Data.MySqlClient.MySqlException): por lo que yo entiendo, está relacionado con una actualización del conector.

Debe agregar Allow User Variables=True en la cadena de conexión para usar variables personalizadas.

Siga este enlace para su referencia:

http://blog.tjitjing.com/index.php/2009/05/mysqldatamysqlclientmysqlexception-parameter-id-must-be-defined.html

6
Zze 22 mar. 2018 a las 07:58

Arriba y abajo toman los mismos tipos de columna. Supongo que desea cambiar solo el nombre de la columna. Me pregunto si puedes probar sin anonimato Argumentos como ese:

public override void Up()
{
    // RenameColumn("Docks", "ProfileId", "SecondId"); // old answer
    RenameColumn("Docks", "ProfileId", "SecondId", anonymousArguments: new { columnType = "int" });
}

public override void Down()
{
    // RenameColumn("Docks", "SecondId", "ProfileId"); // old answer
    RenameColumn("Docks", "SecondId", "ProfileId", anonymousArguments: new { columnType = "int" });
}
0
Adem Catamak 20 mar. 2018 a las 21:26

Cuando ALTERing una columna, debe especificar la definición completa, no solo la única cosa que desea cambiar. Omitió el tipo de datos (INT) y posiblemente otras cosas.

Le sugiero que obtenga la salida para SHOW CREATE TABLE, modifique la línea en cuestión y luego úsela en ALTER. Aunque desordenado, probablemente aún sea más fácil que tratar de reconstruir la descripción completa del campo en cuestión.

En la práctica, es simplemente más fácil hacer la tarea manualmente, no mediante programación.

0
Rick James 21 mar. 2018 a las 14:24