【问题标题】:EF5 Code First Automatic Migrations: Renaming Primary Key gives error: column names in each table must be uniqueEF5 Code First 自动迁移:重命名主键会出错:每个表中的列名必须是唯一的
【发布时间】:2017-08-21 11:56:35
【问题描述】:

我有一个实体Relations,主键为RelId。我想把这个key改成RelationId

首先,我更改了 SSMS 中的列名: SQL Table

然后我使用(在 Visual Studio 中)Rename 将所有引用中的单词 RelId 更改为 RelationId

我认为数据库和代码中的这种更改会说服我的代码使用新命名的主键,但是当我运行项目时会出现以下错误:

每个表中的列名必须是唯一的。表“dbo.Relations”中的列名“RelationId”被指定了多次。

当然,事实并非如此。在表中,RelationId 列仅存在一次。就像 EF5 正在尝试添加另一个具有相同名称的列。

谁能解释一下为什么会出现这个错误以及如何解决它?

全球.asax

protected void Application_Start()
    {

        //Database.SetInitializer<OefenfirmaContext>(new OefenfirmaDropCreateAndSeed());
        Database.SetInitializer<OefenfirmaContext>(new OefenfirmaDropCreateAndSeed());

        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new RazorViewEngine());

        AreaRegistration.RegisterAllAreas();
        RouteConfig.RegisterRoutes(RouteTable.Routes);

        ModelBinders.Binders.Add(typeof(ShoppingCart), new CartModelBinder());
    }

和 OefenfirmaDropCreateAndSeed 类(不再播种):

public class OefenfirmaDropCreateAndSeed : 
    MigrateDatabaseToLatestVersion<OefenfirmaContext, Migrations.Configuration>
{
}

【问题讨论】:

  • 是否有一些代码可以重新创建 dbo.Relations 或尝试重命名列?
  • 如果您想要 Code First,您应该先更改您的代码(而不是数据库),然后让迁移或初始化程序来更改数据库。现在您可能在模型和数据库之间存在某种不匹配。有没有流畅的配置代码?
  • 不是真的,只是 global.asax 中的一个参考。我将编辑问题并发布全局 asax
  • @SteveGreene,不会流利,只是数据注释。

标签: sql-server entity-framework primary-key rename


【解决方案1】:

您正在使用 Add-Migrations 对吗?然后,您无需使用手动脚本在数据库端手动更新。您应该仅在 Add-Migration 脚本中执行此操作。如果您在数据库端手动运行重命名列的脚本,则现有系统生成的 MigrationScripts 和数据库将不同步。因此,在运行/回滚新/旧迁移脚本时,您最终会遇到错误。根据我的理解,请尝试以下步骤

第 1 步:在 Visual Studio Code 中重命名模型类的主键(RelId 为 RelationId)。

第二步:Package Manager Console中运行Add-Migration RenameMyColumn系统会根据模型变化生成Migrationscripts,比如下面。

注意:请验证系统生成的AddColumnDropColumn,而不是系统生成的如下RenameColumn脚本迁移脚本。如果是,请手动删除 AddColumn 和 DropColumn 脚本,并在 up()down() 方法中添加 RenameColumn() 脚本重命名的主键属性。

namespace MyProject.Model.Migrations
{
   using System;
   using System.Data.Entity.Migrations;

   public partial class RenameMyColumn : DbMigration
   {
     public override void Up()
     {
        // Remove the following auto-generated lines(Note:These scripts generated for an example purpose not for primary key)
        AddColumn("dbo.MyTable", "NewColumn", c => c.String(nullable: false, maxLength: 50));
        DropColumn("dbo.MyTable", "OldColumn");

        // Add this line
        RenameColumn("dbo.MyTable", "OldColumn", "NewColumn");
    }

    public override void Down()
    {
        // Remove the following auto-generated lines(Note:These scripts generated for an example purpose not for primary key)
        AddColumn("dbo.MyTable", "OldColumn", c => c.String(nullable: false, maxLength: 50));
        DropColumn("dbo.MyTable", "NewColumn");

        // Add this line
        RenameColumn("dbo.MyTable", "NewColumn", "OldColumn");
    }
  }
}

希望这可以帮助您继续前进!

【讨论】:

  • AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; ContextKey = "Mvc.OefenfirmaCMS.Lib.Data.OefenfirmaContext"; }
  • 对不起,我“进入”得太早了。我的意思是启用了自动迁移。您是否建议我关闭此功能并使用手动迁移?
  • 不,请选择“启用自动迁移”。我的意思是你不应该手动运行 rawscripts 来重命名数据库端的表的主键。您必须按照我提到的上述步骤进行操作。
  • 完成。 RenameMyColumn 类已按照您的建议进行更改。我是否必须使用 PM 控制台中的命令来执行这些更改?请您简要解释一下 UP 和 DOWN 的作用?
  • Update-Database 执行了更改。感谢您对维涅什的支持!你真的帮了我。
猜你喜欢
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 2022-12-03
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
相关资源
最近更新 更多