5
votes

I have a legacy database which I cannot change with two entities with a foreign key property in each entity:

EntityOne
    ForeignKey1 (pointing to EntityTwo.ForeignKey2)

EntityTwo
    ForeignKey2 (pointing to EntityOne.ForeignKey1)

These foreign keys point to eachother. How can I map this relation with EF6? If it isn't possible, is there any workaround?

I tested with a test database which actually has a foreign key relation from EntityOne to EntityTwo and another from EntityTwo to EntityOne and auto generating the model, with code first from database, did not create any relationships between the two tables:

public partial class EntityFrameworkTesting : DbContext
{
    public EntityFrameworkTesting()
        : base("name=EntityFrameworkTesting")
    {
    }

    public virtual DbSet<EntityOne> EntityOne { get; set; }
    public virtual DbSet<EntityTwo> EntityTwo { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    }
}

With some additional trying I've succeeded to build a relationship between these entities. However, I had to delete the foreign key properties from my POCO classes to allow usage of the MapKey function. I would still like to access the foreign key, but when adding the foreign key property again, I receive an error stating: "ForeignKey2: Name: Each property name in a type must be unique. Property name 'ForeignKey2' is already defined.".

Basically I'm looking for the relationship functionality I have now, but with added foreign key property on my POCO class.

modelBuilder.Entity<EntityTwo>()
            .HasRequired(entity => entity.EntityOne)
            .WithRequiredDependent(entity => entity.EntityTwo)
            .Map(m => m.MapKey("ForeignKey2"));
1

1 Answers

1
votes

In this situation you want to use a shared primary key, meaning the PK of the dependent entity is also the FK to the principal entity (and references the principal entity's PK), enforcing a 1..0 relationship. You can view this answer to see how it's configured.

If you can't change your database schema, you're out of luck in EF6. EF6 does not support FK's referencing any candidate key other than the primary key.

EFCore supports FK's referencing alternate candidate keys, but still won't create two mutually referencing FK's - only the FK in the dependent table will be created (or so it seems via my limited testing just now). You can do so via the following FluentAPI configuration (assuming EntityOne is the principal entity):

modelBuilder.Entity<EntityOne>()
    .HasAlternateKey( eo => eo.ForeignKey1 );

modelBuilder.Entity<EntityTwo>()
    .HasOne( et => et.EntityOne )
    .WithOne( eo => eo.EntityTwo )
    .IsRequired()
    .HasForeignKey<EntityTwo>( et => et.ForeignKey2 )
    .HasPrincipalKey<EntityOne>( eo => eo.ForeignKey1 );

EntityOne.ForeignKey1 should be nullable. When testing, I had to manually specify the type parameters for the Has*Key methods, not sure why.