Con EF Code First Fluent API è impossibile. È sempre necessaria almeno una proprietà di navigazione per creare un vincolo di chiave esterna nel database.
Se stai utilizzando le migrazioni Code First, hai la possibilità di aggiungere una nuova migrazione basata sul codice sulla console del gestore pacchetti ( add-migration SomeNewSchemaName
). Se hai cambiato qualcosa con il tuo modello o mappato, verrà aggiunta una nuova migrazione. Se non hai modificato nulla, forza una nuova migrazione utilizzando add-migration -IgnoreChanges SomeNewSchemaName
. La migrazione conterrà solo file vuoti Up
eDown
questo caso, la metodi .
Quindi puoi modificare il Up
metodo aggiungendovi il seguente:
public override void Up()
{
AddForeignKey("ChildTableName", "ParentId", "ParentTableName", "Id",
cascadeDelete: true);
CreateIndex("ChildTableName", "ParentId");
}
L'esecuzione di questa migrazione ( update-database
sulla console di gestione dei pacchetti) eseguirà un'istruzione SQL simile a questa (per SQL Server):
ALTER TABLE [ChildTableName] ADD CONSTRAINT [FK_SomeName]
FOREIGN KEY ([ParentId]) REFERENCES [ParentTableName] ([Id])
CREATE INDEX [IX_SomeName] ON [ChildTableName] ([ParentId])
In alternativa, senza migrazioni, potresti semplicemente eseguire un comando SQL puro usando
context.Database.ExecuteSqlCommand(sql);
dove context
è un'istanza della classe di contesto derivata ed sql
è solo il comando SQL precedente come stringa.
Tieni presente che con tutto questo EF non ha idea che ParentId
sia una chiave esterna che descrive una relazione. EF lo considererà solo come una proprietà scalare ordinaria. In qualche modo tutto quanto sopra è solo un modo più complicato e più lento rispetto alla semplice apertura di uno strumento di gestione SQL e all'aggiunta manuale del vincolo.