我已多次遇到这种情况,我必须在代码优先迁移的数据库中添加或更改FK关系。以这个模型为例:
public sealed class Post : ITenantData {
[Key]
[Required]
public int PostId { get; set; }
public int TenantId { get; set; }
}
在我的Tenant
EntityTypeConfiguration
中,我有以下内容:
HasMany(c => c.Posts)
.WithRequired()
.HasForeignKey(u => u.TenantId);
这正如我所期望的那样 - 当我查询TenantId
时,会使用Posts
Tenant.Posts
列。
但是现在我想要从Post
添加一个虚拟属性到Tenant
,将上面的模型更改为以下内容:
public sealed class Post : ITenantData {
[Key]
[Required]
public int PostId { get; set; }
public int TenantId { get; set; }
public virtual Tenant {get; set; }
}
我更新了Post
EntityTypeConfiguration
:
HasRequired(c => c.Tenant)
.WithMany()
.HasForeignKey(u => u.TenantId);
点击update-database
。我收到一个错误:
操作失败,因为带有名称的索引或统计信息 表'dbo.Post'上已存在'IX_TenantId'。
在输出中,我看到了这个(以及其他内容):
CREATE INDEX [IX_TenantId] ON [dbo].[Post]([TenantId])
随后是堆栈跟踪。这不是一个大问题,因为应用程序正在开发中,我可以杀死数据库。显然我不能在生产中这样做。如何在不删除db的情况下通过迁移执行此简单更改?
答案 0 :(得分:1)
因为您正在使用自动迁移,即使您正在使用
public class MyMigrationConfiguration<TContext> : DbMigrationsConfiguration<TContext>
where TContext : DbContext{
protected MyMigrationConfiguration() {
AutomaticMigrationsEnabled = true; // you can still chnage this later if you do so before triggering Update
AutomaticMigrationDataLossAllowed = true; // you can still chnage this later if you do so before triggering Update
}
}
有些更改需要手动脚本。 索引是那些令人讨厌的领域之一。
我有sqlscripts删除索引方便。
您看到的方案是“drop index”脚本,然后运行自动迁移。 手动迁移更加痛苦。但是一旦你活着并且你计划进行持续的改变,你会很乐意让你这样做。
说完了。可以保持自动,只需使用手动脚本调整数据库。