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与子实体类冲突.
关于如何成功完成这一任务的任何想法?
取决于您使用的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)