Я пытаюсь переименовать столбец с помощью миграции в моей базе данных MySql.

Это моя миграция:

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

Когда я запускаю Update-Database, он выдает мне большую ошибку (если вы хотите увидеть всю ошибку, откройте фрагмент), который включает в себя:

MySql.Data.MySqlClient.MySqlException (0x80004005): должен быть определен параметр '@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.

Подробный режим сгенерировал следующий SQL-запрос перед выдачей ошибки:

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;

Мне было любопытно, поэтому я скопировал и вставил sql в базу данных, и он выполнил, как и ожидалось, без ошибок и успешно переименовал столбец с правильным типом int(11).

Итак, как я могу предотвратить эту ошибку, даже если она генерирует (очевидно) действительный sql?


Редактировать . Хотелось бы отметить, что принятый здесь ответ мне помог, хотя я не использовал dotconnect.

0
Zze 3 Мар 2018 в 07:20

3 ответа

Лучший ответ

Нашел решение вышеуказанной проблемы: (MySql.Data.MySqlClient.MySqlException): насколько я понимаю, это связано с обновлением разъема.

Вам необходимо добавить Allow User Variables=True в строку подключения, чтобы использовать пользовательские переменные.

Перейдите по этой ссылке для справки:

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

6
Zze 22 Мар 2018 в 07:58

Вверх и вниз принимают одинаковые типы столбцов. Я предполагаю, что вы хотите изменить только имя столбца. Интересно, вы можете попробовать без анонимных аргументов, как это:

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 Мар 2018 в 21:26

Когда ALTERing столбец, вы должны указать полное определение, а не только одну вещь, которую вы хотите изменить. Вы пропустили тип данных (INT) и, возможно, другие вещи.

Я предлагаю вам получить выходные данные для SHOW CREATE TABLE, измените одну строку, о которой идет речь, а затем используйте ее в ALTER. Хотя это и грязно, вероятно, это все же проще, чем пытаться восстановить полное описание рассматриваемой области.

На практике это проще сделать вручную, а не программно.

0
Rick James 21 Мар 2018 в 14:24