一些背景。我正在使用:
并且我在上下文中使用了简单的HiLo序列声明。
protected override void OnModelCreating(ModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.ForNpgsqlUseSequenceHiLo();
}
以下哪个创建我的迁移文件:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateSequence(
name: "EntityFrameworkHiLoSequence",
incrementBy: 10);
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SequenceHiLo),
Name = table.Column<string>(maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
// other tables code goes here... All key has
// .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SequenceHiLo)
}
一切正常,但是HiLo分配了奇怪的ID(但仍然是唯一的)。多么奇怪?让我解释。例如:
我有桌子
我为数据库分配了一个简单的种子,如下所示分配ID:
订单:
OrderItem:
角色:
因此,它似乎已为所有表共享HiLo。我以为每张桌子都是HiLo。
当我使用全新的迁移并执行操作时,我也会收到错误消息
dotnet ef database drop && dotnet ef database update
我遇到了错误(从波兰语翻译成英语):
42P07: relation "EntityFrameworkHiLoSequence" already exist
@UPDATE
由于@jpgrassi,我找到了解决奇怪ID的方法。我为每种型号命名为HiLo。看起来像这样:
protected override void OnModelCreating(ModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<OrderItem>()
.Property(b => b.Id)
.ForNpgsqlUseSequenceHiLo("OrderItemsHiLo");
modelBuilder.Entity<Order>()
.Property(b => b.Id)
.ForNpgsqlUseSequenceHiLo("OrdersHiLo");
// More sequences goes below...
}
现在一切听起来合乎逻辑。但是...我有新错误:
42P07: relation "OrderItemsHiLo" already exist
我的Up
部分:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateSequence(
name: "OrderItemsHiLo",
incrementBy: 10);
// more code...
}
在迁移的Down
部分中,我有:
migrationBuilder.DropSequence(name: "OrderItemsHiLo");
我的问题是: 为什么在进行干净迁移时会引发此错误,以及如何消除此错误?
答案 0 :(得分:1)
即使OP编辑了帖子并在我的帮助下基本解决了该问题,我也会发布实际答案,以便遇到相同“问题”的其他人也可以从中受益。
关于生成的“奇怪” ID。您需要为每个实体创建一个序列,因此它们不会“共享” ID。有关提供商文档的更多信息:HiLo Autoincrement Generation
覆盖OnModelCreating
类中的DbContext
并添加以下内容:
modelBuilder.Entity<OrderItem>()
.Property(b => b.Id)
.ForNpgsqlUseSequenceHiLo($"Sequence-{nameof(OrderItem)}");
// same for others you want a sequence
重新添加迁移,您应该具有以下内容:
migrationBuilder.CreateSequence(
name: "Sequence-OrderItem",
incrementBy: 10);
// Order entity code ommited
Id = table.Column<int>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SequenceHiLo)
现在关于您的“第二个”问题,关于在运行dotnet ef database drop
之后无法重新创建数据库,我无法重现它。我创建了一个示例ASP.NET Core App,该示例将EF Core与PostegreSQL结合使用,并且能够正常删除/创建数据库。
我将应用程序推送到了我的GitHub帐户,因此您可以克隆它并自己尝试:efcore-postgres-hilo-sequence