问题描述
我使用代码优先创建了一个数据库模式。我为我的模型创建了一个基类。
public abstract BaSEObject {
public long Id {get;set;}
}
以及扩展我的 BaSEObject
的 Country 类。
public Country : BaSEObject {
public string Name {get;set;}
}
我在 IEntityTypeConfiguration<Country>
类中为 Country
创建了一个 Seed 方法
public class CountryConfiguration : IEntityTypeConfiguration<Country>
{
public void Configure(EntityTypeBuilder<Country> builder)
{
builder.HasData(new Country[] {new Country {Id = 1,Name = "Canada"},new Country{Id = 2,Name = "United-States"}
});
}
}
后来我在 IsActive
中添加了 BaSEObject
,因此在我的种子中添加了 IsActive
。我知道我可以为 IsActive
设置默认值。但问题是并非每个对象在创建时都处于活动状态(业务规则要求)。
public class CountryConfiguration : IEntityTypeConfiguration<Country>
{
public void Configure(EntityTypeBuilder<Country> builder)
{
builder.HasData(new Country[] {
new Country{Id = 1,Name = "Canada",IsActive = true},Name = "United-States",IsActive = true}
});
}
}
问题是,当我运行 Add-Migration
时,国家的种子不会重新生成,因此当我运行 Update-Database
时,IsActive
列会自动设置为 false。
EFCore 有没有办法重新生成种子数据?
编辑:包含原始种子的迁移是第一次迁移。我们目前有 15 个左右。
我想知道如何强制种子再生而不必重做任何迁移。
解决方法
您可以使用 Remove-Migration
删除上次迁移并重新构建或添加具有不同名称的迁移,例如 Add-Migration SeedDataUpdated
(如果这次迁移不是最后一次迁移,请查看 these answers 如何回滚),否则没有用于重新生成/更新迁移的命令。
如果您删除了上次迁移并重新创建了迁移,它应该如下所示。 (Remove-Migration
-> Add-Migration SeedData
)
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsActive",table: "Users",type: "bit",nullable: false,defaultValue: false);
migrationBuilder.InsertData(
table: "Users",columns: new[] { "Id","Name","IsActive" },values: new object[] { 1,"Canada",true });
migrationBuilder.InsertData(
table: "Users",values: new object[] { 2,"United-States",true });
}
如果您创建了一个新的迁移 (Add-Migration SeedDataUpdated
),它应该如下所示。
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsActive",table: "Countries",defaultValue: false);
migrationBuilder.UpdateData(
table: "Countries",keyColumn: "Id",keyValue: 1,column: "IsActive",value: true);
migrationBuilder.UpdateData(
table: "Countries",keyValue: 2,value: true);
}