【问题标题】:EF Rename Column in MySql databaseMySql数据库中的EF重命名列
【发布时间】:2018-03-03 04:20:30
【问题描述】:

我正在尝试通过 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 时,它向我吐出一个大错误(如果你想查看整个错误,请打开 sn-p),其中包括:

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 复制并粘贴到 db 中,它按预期执行而没有错误,并成功地用正确类型的 int(11) 重命名了列。

那么,即使它正在生成(显然)有效的 sql,我该如何防止抛出此错误?


编辑:想指出,即使我没有使用 dotconnect,这里接受的答案也对我有用。

【问题讨论】:

  • 您确定要使用 EF 定位正确的数据库吗?如果数据库架构不正确,第一个查询将返回 NULL,因此将提供不正确的语法,并应准确抛出您所看到的错误。
  • @DevilSuichiro 到目前为止,我的所有迁移都有效,并且该应用程序当前有效。
  • 生成的 SQL 是什么?

标签: c# mysql entity-framework


【解决方案1】:

找到上述问题的解决方案:(MySql.Data.MySqlClient.MySqlException):据我了解,这与连接器的升级有关。

您需要在连接字符串中添加Allow User Variables=True 才能使用自定义变量。

点击此链接供您参考:

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

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • 我是这个网站的新用户,所以对以下标准没有太多了解。仍然会记住。
  • @Mrunalini 审阅者建议您应该通过从链接中复制相关信息(即代码 sn-p)来改进您的答案,然后将其发布在您的答案中。这样做的原因是,如果该链接失效,那么与您的帖子相关的所有信息都将丢失。
  • 肯定会改进回答问题的方式。
  • @Zze 很高兴听到这个消息..:)
【解决方案2】:

Up 和 Down 采用相同的列类型。我假设您只想更改列名。我想知道您可以尝试不使用这样的匿名参数:

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

【讨论】:

  • 不幸的是,我也试过这个,但它不起作用。感谢您的回答,我会在我的问题中更清楚地表明我已经尝试过这个。
  • 如果我问你能不能用像“columnType”这样的小写字母试试(ColumnType)?我编辑我的答案
  • 我回家后会试试这个。
【解决方案3】:

ALTERing 列时,您必须指定整个定义,而不仅仅是您要更改的一件事。您遗漏了数据类型 (INT),可能还有其他内容。

我建议您获取SHOW CREATE TABLE 的输出,修改有问题的一行,然后在ALTER 中使用它。虽然很混乱,但它可能仍然比尝试重建相关领域的完整描述更容易。

在实践中,手动完成任务更容易,而不是编程。

【讨论】:

  • 您能否详细说明我需要包含数据类型的语法。
  • 我添加到我的答案中。
猜你喜欢
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 2023-03-26
  • 2011-08-19
  • 2020-04-30
  • 2017-10-04
相关资源
最近更新 更多