Search code examples
c#entity-frameworkcode-first

EF Code First, two navigation properties to same object


I'm using EF Code First to query and create a database. One of my entities (relationship) has two navigation properties to the same entity (activity). My problem is that if I use EF to create the database schema it will create four foreign key columns and constraints instead of two.

Here are the relevant code parts:

activity class:

public class Activity {
    public virtual ICollection<Relationship> Successors { get; set; }
    public virtual ICollection<Relationship> Predecessors { get; set; }
}

relationship class:

public class Relationship {
    public virtual Activity Activity1 { get; set; }
    public int Activity1_ID { get; set; }
    public virtual Activity Activity2 { get; set; }
    public int Activity2_ID { get; set; }
}

Relationship mapping class:

this.HasRequired(t => t.Activity1)
  .WithMany(t => t.Predecessors)
  .HasForeignKey(m => m.Activity1_ID)
  .WillCascadeOnDelete(false);
this.HasRequired(t => t.Activity2)
  .WithMany(t => t.Successors)
  .HasForeignKey(m => m.Activity2_ID)
  .WillCascadeOnDelete(false);

Database structure: enter image description here

Is there a way to prevent the creation of the last two columns?


Solution

  • This should create you only 2 foreign key columns.

    public class Activity
    {
        public int Id { set; get; }
        public virtual ICollection<Relationship> Successors { get; set; }
        public virtual ICollection<Relationship> Predecessors { get; set; }
    }
    public class Relationship
    {
        public int Id { set; get; }
        public virtual Activity Activity1 { get; set; }
        public int Activity1_ID { get; set; }
        public virtual Activity Activity2 { get; set; }
        public int Activity2_ID { get; set; }
    }
    

    And the DbContext class where i am specifying the relationship/FK nature on my OnModelCreating.

    public class MyDb: DbContext
    {
        public MyDb():base("EfDbContext")
        {           
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {            
            modelBuilder.Entity<Relationship>()
                .HasRequired(f => f.Activity1)
                .WithMany(f => f.Predecessors)
                .HasForeignKey(g => g.Activity1_ID)
                .WillCascadeOnDelete(false);
    
            modelBuilder.Entity<Relationship>().
                 HasRequired(f => f.Activity2)
                .WithMany(f => f.Successors)
                .HasForeignKey(g => g.Activity2_ID)
                .WillCascadeOnDelete(false);
        }
    }
    

    enter image description here