Sto realizzando la progettazione del framework di entità primo di codice.
Ho una tabella, Account, che ha una proprietà, Supervisore:
public class Account
{
public int Id { get; set; }
public Account Supervisor { get; set; }
}
Funziona magnificamente.
Tuttavia, desidero aggiungere un supervisore alternativo alla classe:
public class Account
{
public int Id { get; set; }
public Account Supervisor { get; set; }
public Account AlternateSupervisor { get; set; }
}
Quando eseguo Add-Migration AddAlternateSupervisor, il codice generato mi dà quanto segue:
public partial class AddAlternateSupervisor : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Accounts_SupervisorId",
table: "Accounts");
migrationBuilder.DropIndex(
name: "IX_Accounts_SupervisorId",
table: "Accounts");
migrationBuilder.AddColumn<int>(
name: "AlternateSupervisorId",
table: "Accounts",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Accounts_AlternateSupervisorId",
table: "Accounts",
column: "AlternateSupervisorId",
unique: true,
filter: "[AlternateSupervisorId] IS NOT NULL");
migrationBuilder.AddForeignKey(
name: "FK_Accounts_Accounts_AlternateSupervisorId",
table: "Accounts",
column: "AlternateSupervisorId",
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
// snip
}
Come puoi vedere, EF sta cercando di rinominare il mio riferimento da Supervisore a AlternateSupervisor. Non lo voglio, voglio che sia Supervisor sia AlternateSupervisor facciano riferimento ad altri account.
So che EF non è in grado di gestire più relazioni molte-a-molte, ma queste sono relazioni uno a uno. Non riesco a trovare alcuna informazione sul perché EF stia generando la migrazione in questo modo.
Allora perché Entity Framework sta cercando di rinominare Supervisor in AlternateSupervisor e come posso forzarlo a generare entrambi i collegamenti?
EDIT: a questa domanda è stata data una risposta come inizialmente richiesto. Tuttavia, vorrei aggiungere che, come chiesto, la domanda non ha molto senso per il dominio. Chi ha mai sentito parlare di un account in grado di supervisionare esattamente solo un altro account? La relazione è una relazione una a molte, che si risolve con l'uso di WithMany anziché WithOne.
EF Core non può mappare più one-to-one
con la stessa entità per convenzione. Devi farlo con l' Fluent API
come segue:
La tua classe di Account
:
public class Account
{
public int Id { get; set; }
public int SupervisorId { get; set; }
public Account Supervisor { get; set; }
public int AlternateSupervisorId { get; set; }
public Account AlternateSupervisor { get; set; }
}
Quindi in OnModelCreating
di DbContext
come segue:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Account>().HasOne(a => a.Supervisor).WithOne()
.HasForeignKey<Account>(a => a.SupervisorId).OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Account>().HasOne(a => a.AlternateSupervisor).WithOne()
.HasForeignKey<Account>(a => a.AlternateSupervisorId).OnDelete(DeleteBehavior.Restrict);
}
Ora tutto genererà come previsto!
Nota: ho aggiunto la chiave esterna SupervisorId
e AlternateSupervisorId
esplicito alla classe del modello di Account
per la leggibilità. Se non li desideri esplicitamente, la configurazione Fluent API
dovrebbe essere la seguente:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Account>().HasOne(a => a.Supervisor)
.WithOne().OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Account>().HasOne(a => a.AlternateSupervisor)
.WithOne().OnDelete(DeleteBehavior.Restrict);
}