Create one to one relationship optional on both sides in EF6

ef-fluent-api entity-framework entity-framework-6

Question

Is there a way to map two entities to have one to one relationship optional on both sides using fluent API in Entity Framework 6?

Code example:

// Subscription (has FK OrderId)
this.HasOptional(t => t.Order)
    .WithOptionalDependent(t => t.Subscription)
    .HasForeignKey(d => d.OrderId); // does not compile

Context: why would I do this? I work in an existing system where there are payment orders to buy subscriptions. When a order get paid a subscription is created and associated whit it, meaning subscription is optional to order. Also, there are other ways to create subscriptions, meaning order is optional to subscription.

1
2
5/22/2015 4:14:57 PM

Popular Answer

Usually in an one-to-one (or zero) relationship both entities shares the same PK and, in the dependent one, the PK is also specified as FK. Check this link for more info about this. But if you entities not share the same PK, then you can't add a FK property in the dependent entity. If you do that, EF will throw an exception related with the multiplicity saying that it must be *.

About the relationship's configuration, there is only one way to configure an one-to-one relationship with both sides as optional, which it is what you currently have using Fluent Api. This way you can also use the Map method to rename the FK column that EF create by convention in the dependent table by the name that you already have in the Subscription table in your DB.

Update

If you were not tied to an existing database, you could do something like this:

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; }
}

And the configuration would be this:

 modelBuilder.Entity<Subscription>()
            .HasOptional(s => s.Order)
            .WithMany()
            .HasForeignKey(s=>s.OrderId);

 modelBuilder.Entity<>(Order)
            .HasOptional(s => s.Subscription)
            .WithMany()
            .HasForeignKey(s=>s.SubscriptionId);

This way you can work with the OrderIdFK (and SubscriptionId too) like it was a one-to-one relationship. The problem here is you have to set and save both associations separately.

1
5/23/2015 1:20:57 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow