C'è un modo per mappare due entità per avere una relazione uno-a-uno opzionale su entrambi i lati usando l'API fluente in Entity Framework 6?
Esempio di codice :
// Subscription (has FK OrderId)
this.HasOptional(t => t.Order)
.WithOptionalDependent(t => t.Subscription)
.HasForeignKey(d => d.OrderId); // does not compile
Contesto: perché dovrei farlo? Lavoro in un sistema esistente in cui sono presenti ordini di pagamento per acquistare abbonamenti. Quando un ordine viene pagato, viene creato e associato un abbonamento, il che significa che l'abbonamento è facoltativo per l'ordine. Inoltre, ci sono altri modi per creare abbonamenti, il che significa che l'ordine è facoltativo per l'abbonamento.
Solitamente in una relazione one-to-one (o zero) entrambe le entità condividono lo stesso PK e, in quella dipendente, anche il PK viene specificato come FK. Controlla questo link per maggiori informazioni su questo. Ma se le entità non condividono lo stesso PK, non è possibile aggiungere una proprietà FK nell'entità dipendente. Se lo fai, EF genererà un'eccezione relativa alla molteplicità dicendo che deve essere *.
Per quanto riguarda la configurazione della relazione, esiste un solo modo per configurare una relazione uno a uno con entrambi i lati come facoltativo, che è ciò che attualmente si utilizza con Fluent Api. In questo modo puoi anche usare il metodo Map per rinominare la colonna FK che EF crea per convenzione nella tabella dipendente con il nome che hai già nella tabella Subscription
nel tuo DB.
Se non fossi legato a un database esistente, potresti fare qualcosa del genere:
public class Subscription
{
public int SubscriptionId { get; set; }
public int? OrderId { get; set; }
public virtual Order Order { get; set; }
}
public class Order
{
public int OrderId { get; set; }
public int SubscriptionId { get; set; }
public virtual Subscription Subscription { get; set; }
}
E la configurazione sarebbe questa:
modelBuilder.Entity<Subscription>()
.HasOptional(s => s.Order)
.WithMany()
.HasForeignKey(s=>s.OrderId);
modelBuilder.Entity<>(Order)
.HasOptional(s => s.Subscription)
.WithMany()
.HasForeignKey(s=>s.SubscriptionId);
In questo modo puoi lavorare anche con OrderId
(e SubscriptionId
) come se fosse una relazione one-to-one. Il problema qui è che devi impostare e salvare entrambe le associazioni separatamente.