如何在EF Code First中更改主键的名称?

Kom*_*gem 12 c# ef-migrations entity-framework-5

我有一个场景,我想更改实体中的主键名称,并能够运行update-database -force.当我尝试时,请参阅下面的代码和错误.

实体是:

public class Team
{
    [Key]
    [HiddenInput(DisplayValue = false)]
    public virtual int Id { get; set; }

    [Display(Name = "Full Name:")]
    public virtual string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

实体更改为:

public class Team
{
    [Key]
    [HiddenInput(DisplayValue = false)]
    public virtual int TeamId { get; set; }

    [Display(Name = "Full Name:")]
    public virtual string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我运行时,Update-database -Force我得到以下错误.

Multiple identity columns specified for table 'Teams'. Only one identity column per table is allowed.

它是命名约定的问题,当我引用后者时,我需要将它作为TeamId,简单地说就是Id与子实体类冲突.

关于如何成功完成这一任务的任何想法?

Dry*_*ods 6

取决于您使用的EF版本.即使迁移,您将看到的结果如下:

"drop column Id"和"add column TeamId".

有了这个,你将失去所有的价值观和"儿童联系"......

我在这一点上看到的唯一"安全"解决方案是迁移和"手动SQL操作"的混合.

EASY解决方案:

1-考虑到您已经创建了具有ID的表的"基础"迁移,现在使用"更新"创建新的迁移.现在不要运行它.

2-打开该文件并在生成的行之前写一个新行并使用SQL命令,如下所示:

     SQL("ALTER TABLE table_name RENAME COLUMN old_name to new_name;");
Run Code Online (Sandbox Code Playgroud)

这将更改名称在迁移删除列并创建新列之前,将会发生的事情是:在删除之前更改名称,然后执行删除但它将"失败"但不会造成任何伤害.

但现在你问:为什么我这样做?好吧,如果你使用迁移,即使你删除了删除列并创建一个新的行,下次你自动创建一个新的迁移文件时,这些新的行将在那里......这就是原因.

更新的答案#1

当我谈到实体框架迁移时,我指的是:http: //blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx 在程序包管理器控制台中运行"添加 - 迁移AddBlogUrl"命令时,将创建一个新文件(*.cs).

带有SQL命令的此文件迁移文件的示例:

public partial class AddAbsencesTypesAndCategories : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "pvw_AbsenceType",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Name = c.String(nullable: false),
                        CountAsVacation = c.Boolean(nullable: false),
                        IsIncremental = c.Boolean(nullable: false),
                    })
                .PrimaryKey(t => t.Id);

          .....

            AddColumn("pvw_Absence", "CategoryId", c => c.Int(nullable: false));
                        AddForeignKey("pvw_Absence", "StatusId", "pvw_AbsenceStatusType", "Id");
            AddForeignKey("pvw_Absence", "CategoryId", "pvw_AbsenceType", "Id");
            CreateIndex("pvw_Absence", "StatusId");
            CreateIndex("pvw_Absence", "CategoryId");
            DropColumn("pvw_Absence", "MainCategoryId");
            DropColumn("pvw_Absence", "SubCategoryId");
           ......
            Sql(@"
                                        SET IDENTITY_INSERT [dbo].[pvw_AbsenceStatusType] ON
                    INSERT pvw_AbsenceStatusType (Id, Name) VALUES (1, N'Entwurf')                       
                                        SET IDENTITY_INSERT [dbo].[pvw_AbsenceStatusType] OFF
            ");    
            .....
        }

        public override void Down()
        {
            ........
        }
Run Code Online (Sandbox Code Playgroud)