EF Core Fluent API HasData 在后续迁移中添加删除数据
EF Core Fluent API HasData adding delete data on subsequent migration
我正在使用 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; }
}
基础实体
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, CountryId = 1, CountyName = "Carlow"},
new County { Id = 3, CountryId = 1, CountyName = "Cavan"},
new County { Id = 4, CountryId = 1, CountyName = "Clare"},
new County { Id = 5, CountryId = 1, CountyName = "Cork"},
new County { Id = 6, CountryId = 1, CountyName = "Derry (Londonderry)"},
new County { Id = 7, CountryId = 1, CountyName = "Donegal"},
new County { Id = 8, CountryId = 1, CountyName = "Dublin"},
new County { Id = 9, CountryId = 1, CountyName = "Galway"},
new County { Id = 10, CountryId = 1, CountyName = "Kerry"},
new County { Id = 11, CountryId = 1, CountyName = "Kildare"},
new County { Id = 12, CountryId = 1, CountyName = "Kilkenny"},
new County { Id = 13, CountryId = 1, CountyName = "Laois (Queens)"},
new County { Id = 14, CountryId = 1, CountyName = "Leitrim"},
new County { Id = 15, CountryId = 1, CountyName = "Limerick"},
new County { Id = 16, CountryId = 1, CountyName = "Longford"},
new County { Id = 17, CountryId = 1, CountyName = "Louth"},
new County { Id = 18, CountryId = 1, CountyName = "Mayo"},
new County { Id = 19, CountryId = 1, CountyName = "Meath"},
new County { Id = 20, CountryId = 1, CountyName = "Monaghan"},
new County { Id = 21, CountryId = 1, CountyName = "Offaly (Kings)"},
new County { Id = 22, CountryId = 1, CountyName = "Roscommon"},
new County { Id = 23, CountryId = 1, CountyName = "Sligo"},
new County { Id = 24, CountryId = 1, CountyName = "Tipperary"},
new County { Id = 25, CountryId = 1, CountyName = "Waterford"},
new County { Id = 26, CountryId = 1, CountyName = "Westmeath"},
new County { Id = 27, CountryId = 1, CountyName = "Wexford"},
new County { Id = 28, CountryId = 1, 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, 1, "Westmeath" },
{ 25, 1, "Waterford" },
{ 24, 1, "Tipperary" },
{ 23, 1, "Sligo" },
{ 22, 1, "Roscommon" },
{ 21, 1, "Offaly (Kings)" },
{ 20, 1, "Monaghan" },
{ 19, 1, "Meath" },
{ 18, 1, "Mayo" },
{ 17, 1, "Louth" },
{ 16, 1, "Longford" },
{ 27, 1, "Wexford" },
{ 15, 1, "Limerick" },
{ 13, 1, "Laois (Queens)" },
{ 12, 1, "Kilkenny" },
{ 11, 1, "Kildare" },
{ 10, 1, "Kerry" },
{ 9, 1, "Galway" },
{ 8, 1, "Dublin" },
{ 7, 1, "Donegal" },
{ 6, 1, "Derry (Londonderry)" },
{ 5, 1, "Cork" },
{ 4, 1, "Clare" },
{ 2, 1, "Carlow" },
{ 14, 1, "Leitrim" },
{ 28, 1, "Wicklow" }
});
migrationBuilder.CreateIndex(
name: "IX_Counties_CountryId",
table: "Counties",
column: "CountryId");
migrationBuilder.CreateIndex(
name: "IX_Counties_CountyName_CountryId",
table: "Counties",
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",
keyColumn: "Id",
keyValue: 1);
migrationBuilder.InsertData(
table: "Counties",
columns: new[] { "Id", "CountryId", "CountyName" },
values: new object[] { 1, 1, "Antrim" });
}
}
不确定,为什么要添加 migrationBuilder.DeleteData
删除脚本?
这里
entity.HasOne(c => c.Country).WithOne().OnDelete(DeleteBehavior.Cascade);
with 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 索引约定的默认配置。
我正在使用 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; }
}
基础实体
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, CountryId = 1, CountyName = "Carlow"},
new County { Id = 3, CountryId = 1, CountyName = "Cavan"},
new County { Id = 4, CountryId = 1, CountyName = "Clare"},
new County { Id = 5, CountryId = 1, CountyName = "Cork"},
new County { Id = 6, CountryId = 1, CountyName = "Derry (Londonderry)"},
new County { Id = 7, CountryId = 1, CountyName = "Donegal"},
new County { Id = 8, CountryId = 1, CountyName = "Dublin"},
new County { Id = 9, CountryId = 1, CountyName = "Galway"},
new County { Id = 10, CountryId = 1, CountyName = "Kerry"},
new County { Id = 11, CountryId = 1, CountyName = "Kildare"},
new County { Id = 12, CountryId = 1, CountyName = "Kilkenny"},
new County { Id = 13, CountryId = 1, CountyName = "Laois (Queens)"},
new County { Id = 14, CountryId = 1, CountyName = "Leitrim"},
new County { Id = 15, CountryId = 1, CountyName = "Limerick"},
new County { Id = 16, CountryId = 1, CountyName = "Longford"},
new County { Id = 17, CountryId = 1, CountyName = "Louth"},
new County { Id = 18, CountryId = 1, CountyName = "Mayo"},
new County { Id = 19, CountryId = 1, CountyName = "Meath"},
new County { Id = 20, CountryId = 1, CountyName = "Monaghan"},
new County { Id = 21, CountryId = 1, CountyName = "Offaly (Kings)"},
new County { Id = 22, CountryId = 1, CountyName = "Roscommon"},
new County { Id = 23, CountryId = 1, CountyName = "Sligo"},
new County { Id = 24, CountryId = 1, CountyName = "Tipperary"},
new County { Id = 25, CountryId = 1, CountyName = "Waterford"},
new County { Id = 26, CountryId = 1, CountyName = "Westmeath"},
new County { Id = 27, CountryId = 1, CountyName = "Wexford"},
new County { Id = 28, CountryId = 1, 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, 1, "Westmeath" },
{ 25, 1, "Waterford" },
{ 24, 1, "Tipperary" },
{ 23, 1, "Sligo" },
{ 22, 1, "Roscommon" },
{ 21, 1, "Offaly (Kings)" },
{ 20, 1, "Monaghan" },
{ 19, 1, "Meath" },
{ 18, 1, "Mayo" },
{ 17, 1, "Louth" },
{ 16, 1, "Longford" },
{ 27, 1, "Wexford" },
{ 15, 1, "Limerick" },
{ 13, 1, "Laois (Queens)" },
{ 12, 1, "Kilkenny" },
{ 11, 1, "Kildare" },
{ 10, 1, "Kerry" },
{ 9, 1, "Galway" },
{ 8, 1, "Dublin" },
{ 7, 1, "Donegal" },
{ 6, 1, "Derry (Londonderry)" },
{ 5, 1, "Cork" },
{ 4, 1, "Clare" },
{ 2, 1, "Carlow" },
{ 14, 1, "Leitrim" },
{ 28, 1, "Wicklow" }
});
migrationBuilder.CreateIndex(
name: "IX_Counties_CountryId",
table: "Counties",
column: "CountryId");
migrationBuilder.CreateIndex(
name: "IX_Counties_CountyName_CountryId",
table: "Counties",
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",
keyColumn: "Id",
keyValue: 1);
migrationBuilder.InsertData(
table: "Counties",
columns: new[] { "Id", "CountryId", "CountyName" },
values: new object[] { 1, 1, "Antrim" });
}
}
不确定,为什么要添加 migrationBuilder.DeleteData
删除脚本?
这里
entity.HasOne(c => c.Country).WithOne().OnDelete(DeleteBehavior.Cascade);
with 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 索引约定的默认配置。