我正在尝试通过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 :(得分:3)
找到上述问题的解决方案:(MySql.Data.MySqlClient.MySqlException):据我所知,它与连接器的升级有关。
您需要在连接字符串中添加Allow User Variables=True
才能使用自定义变量。
请点击此链接以供参考:
答案 1 :(得分:0)
上下采用相同的列类型。我假设您只想更改列名称。我想你可以尝试没有像这样的匿名参数:
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" });
}
答案 2 :(得分:0)
当ALTERing
列时,您必须指定整个定义,而不仅仅是您要更改的内容。你遗漏了数据类型(INT),可能还有其他东西。
我建议您获取SHOW CREATE TABLE
的输出,修改相关的一行,然后在ALTER
中使用该输出。虽然很乱,但它可能比试图重建有关领域的完整描述更容易。
在实践中,手动执行任务更容易,而不是以编程方式执行。