问题描述
我正在使用 HasData
来播种数据,它正在正确创建插入数据迁移脚本,但在随后的迁移中,它添加了删除迁移,无需任何进一步更改。
实体
国家
public class Country : BaseEntity
{
public string CountryName { get; set; }
}
县
public class County : BaseEntity
{
public string CountyName { get;set; }
public int CountryId { get;set; }
public Country Country { get; set; }
}
BaseEntity
public class BaseEntity
{
public int Id { get; set; }
public Guid ApplicationUserId { get; set; }
}
配置
public class CountyConfiguration : BaseEntityConfiguration<County>
{
private const string TABLE_NAME = "Counties";
public CountyConfiguration() : base(TABLE_NAME)
{
}
public override void Configure(EntityTypeBuilder<County> entity)
{
base.Configure(entity);
entity.Property(c => c.CountyName).Isrequired().HasMaxLength(100);
entity.HasIndex(c => c.CountryId).IsUnique(false);
entity.HasIndex(c => new {c.CountyName,c.CountryId }).IsUnique();
entity.HasOne(c => c.Country).WithOne().OnDelete(DeleteBehavior.Cascade);
entity.Ignore(c => c.ApplicationUserId);
entity.HasData(
new County { Id = 1,CountryId = 1,CountyName = "Antrim"},new County { Id = 2,CountyName = "Carlow"},new County { Id = 3,CountyName = "Cavan"},new County { Id = 4,CountyName = "Clare"},new County { Id = 5,CountyName = "Cork"},new County { Id = 6,CountyName = "Derry (Londonderry)"},new County { Id = 7,CountyName = "Donegal"},new County { Id = 8,CountyName = "dublin"},new County { Id = 9,CountyName = "galway"},new County { Id = 10,CountyName = "Kerry"},new County { Id = 11,CountyName = "Kildare"},new County { Id = 12,CountyName = "Kilkenny"},new County { Id = 13,CountyName = "Laois (Queens)"},new County { Id = 14,CountyName = "Leitrim"},new County { Id = 15,CountyName = "Limerick"},new County { Id = 16,CountyName = "Longford"},new County { Id = 17,CountyName = "Louth"},new County { Id = 18,CountyName = "Mayo"},new County { Id = 19,CountyName = "Meath"},new County { Id = 20,CountyName = "Monaghan"},new County { Id = 21,CountyName = "Offaly (Kings)"},new County { Id = 22,CountyName = "Roscommon"},new County { Id = 23,CountyName = "Sligo"},new County { Id = 24,CountyName = "Tipperary"},new County { Id = 25,CountyName = "Waterford"},new County { Id = 26,CountyName = "Westmeath"},new County { Id = 27,CountyName = "Wexford"},new County { Id = 28,CountyName = "Wicklow"}
);
}
}
生成的迁移 1:
public partial class County : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Counties",columns: table => new
{
Id = table.Column<int>(type: "int",nullable: false)
.Annotation("sqlServer:Identity","1,1"),CountyName = table.Column<string>(type: "nvarchar(100)",maxLength: 100,nullable: false),CountryId = table.Column<int>(type: "int",nullable: false)
},constraints: table =>
{
table.PrimaryKey("Pk_Counties_Id",x => x.Id);
table.ForeignKey(
name: "FK_Counties_Countries_CountryId",column: x => x.CountryId,principalTable: "Countries",principalColumn: "Id",onDelete: referentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Counties",columns: new[] { "Id","CountryId","CountyName" },values: new object[,]
{
{ 3,1,"Cavan" },{ 26,"Westmeath" },{ 25,"Waterford" },{ 24,"Tipperary" },{ 23,"Sligo" },{ 22,"Roscommon" },{ 21,"Offaly (Kings)" },{ 20,"Monaghan" },{ 19,"Meath" },{ 18,"Mayo" },{ 17,"Louth" },{ 16,"Longford" },{ 27,"Wexford" },{ 15,"Limerick" },{ 13,"Laois (Queens)" },{ 12,"Kilkenny" },{ 11,"Kildare" },{ 10,"Kerry" },{ 9,"galway" },{ 8,"dublin" },{ 7,"Donegal" },{ 6,"Derry (Londonderry)" },{ 5,"Cork" },{ 4,"Clare" },{ 2,"Carlow" },{ 14,"Leitrim" },{ 28,"Wicklow" }
});
migrationBuilder.CreateIndex(
name: "IX_Counties_CountryId",table: "Counties",column: "CountryId");
migrationBuilder.CreateIndex(
name: "IX_Counties_CountyName_CountryId",columns: new[] { "CountyName","CountryId" },unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Counties");
}
}
下一次迁移 2:(没有任何变化)
public partial class Empty : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "Counties",keyColumn: "Id",keyvalue: 1);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "Counties",keyvalue: 1);
migrationBuilder.InsertData(
table: "Counties",values: new object[] { 1,"Antrim" });
}
}
不确定,为什么要添加 migrationBuilder.DeleteData
删除脚本?
解决方法
这里
entity.HasOne(c => c.Country).WithOne().OnDelete(DeleteBehavior.Cascade);
使用 WithOne()
,您基本上是在告诉 EF County.CountryId
必须是唯一的(因为关系数据库中一对一和一对多之间的唯一区别是唯一约束(索引) 用于 FK 列)。
但是,在此之前,您告诉 EF 正好相反
entity.HasIndex(c => c.CountryId).IsUnique(false);
这一系列冲突的配置不知何故混淆了 EF,它开始做奇怪的事情。
虽然这可以被视为他们的错误,但最终问题出在您的代码中,因为显然您不想要一对一的关系。因此,通过将 HasOne
替换为 HasMany
entity.HasOne(c => c.Country).WithMany().OnDelete(DeleteBehavior.Cascade);
或完全删除它,因为它所做的一切都与默认的 EF Core 约定相同。
执行此操作后,您还可以删除 HasIndex
配置,因为它也是 EF Core FK 索引约定的默认设置。