Un piccolo sfondo. Sto usando:
e sto usando quella semplice dichiarazione di sequenza HiLo nel mio contesto.
protected override void OnModelCreating(ModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
modelBuilder.ForNpgsqlUseSequenceHiLo();
}
Che crea i miei file di migrazione come segue:
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)
}
Tutto funziona, ma HiLo sta assegnando strani ID (ma comunque unici). Che strano? Lasciatemi spiegare. Per esempio:
Ho dei tavoli
E faccio un semplice seed nel database che assegna gli ID come segue:
Ordini:
OrderItem:
ruoli:
Quindi sembra che abbia condiviso HiLo per tutte le tabelle. Ho pensato che fosse HiLo per tavolo.
Inoltre ricevo un errore quando utilizzo la nuova migrazione pulita e faccio:
dotnet ef database drop && dotnet ef database update
Ho un errore (tradotto in inglese dal polacco):
42P07: relation "EntityFrameworkHiLoSequence" already exist
@AGGIORNARE
Grazie a @jpgrassi ho trovato la soluzione per strani ID. Ho creato HiLo per ogni modello. Sembra così:
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...
}
Ora sembra tutto logico. Ma ... ho un nuovo errore:
42P07: relation "OrderItemsHiLo" already exist
La mia Up
sezione:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateSequence(
name: "OrderItemsHiLo",
incrementBy: 10);
// more code...
}
E nella mia sezione Down
in migrazione ho:
migrationBuilder.DropSequence(name: "OrderItemsHiLo");
La mia domanda è: perché questo errore viene generato in caso di migrazione pulita e come eliminarlo?
@AGGIORNARE
Ho appena rimosso quella riga e risolto il mio secondo problema. Che stupido...
_context.Database.EnsureCreatedAsync();
Anche se OP ha modificato il post e praticamente risolto il problema con il mio aiuto, posterò una risposta reale in modo che altri che si imbattono nello stesso "problema" possano trarne beneficio.
Per quanto riguarda lo "strano" ID generato. Devi creare una sequenza per entità, quindi non "condividono" gli ID. Maggiori informazioni sulla documentazione del provider: Generazione di incremento automatico HiLo
Sostituisci OnModelCreating
nella tua classe DbContext
e aggiungi questo:
modelBuilder.Entity<OrderItem>()
.Property(b => b.Id)
.ForNpgsqlUseSequenceHiLo($"Sequence-{nameof(OrderItem)}");
// same for others you want a sequence
Aggiungi nuovamente le migrazioni e dovresti avere qualcosa del genere:
migrationBuilder.CreateSequence(
name: "Sequence-OrderItem",
incrementBy: 10);
// Order entity code ommited
Id = table.Column<int>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SequenceHiLo)
Ora, per quanto riguarda la tua "seconda" domanda, sul fatto di non essere in grado di ricreare il database dopo aver eseguito il dotnet ef database drop
non sono stato in grado di riprodurlo. Ho creato un'app ASP.NET Core di esempio che utilizza EF Core con PostegreSQL e sono stato in grado di eliminare / creare normalmente il db.
Ho spinto l'app sul mio account GitHub, così puoi clonarla e provarla tu stesso: efcore-postgres-hilo-sequence