Over a million developers have joined DZone.

How to Configure a Self Referencing Entity in Code First

·

A few days ago a worker in Sela asked me how to configure a self referencing entity with EF Code First. In this post I’ll show you how to implement that configuration.

Self Reference Scenarios

There are a lot of scenarios that we will want to implement a self reference between an entity to itself. For example, we do that when we want to create hierarchies in our application - an employee entity that has a self reference to his/her manager is a very common scenario for that. When we want to create that behavior in a database all we have to do is to add a foreign key in the table that point to the table primary key and we are done. But how can we do that in EF Code First?

Configure a Self Reference in Code First

In EF Code First we can use the fluent API in order to configure a self reference. Lets jump into an example that will direct you how to make that configuration.
The first thing is the entity: 

public class Employee
{
  #region Properties
 
  public int EmployeeID { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
 
  public int? ManagerID { get; set; }
  public Employee Manager { get; set; }
 
  #endregion
}

As you might notice there is nothing interesting in the entity itself – just a bunch of properties and the reference to the manager which is another employee.
After we have the entity lets create the context: 

public class CompanyContext : DbContext
{
  #region Properties
 
  public DbSet<Employee> Employees { get; set; }
 
  #endregion
 
  #region Ctor
 
  public CompanyContext()
    : base("Company")
  {
  }
 
  #endregion
 
  #region Methods
 
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    modelBuilder.Entity<Employee>().
      HasOptional(e => e.Manager).
      WithMany().
      HasForeignKey(m => m.ManagerID);
  }
 
  #endregion
}

In the context you need to implement the OnModelCreating method in order to configure the self reference. We start the configuration with the HasOptional method that indicate that the employee might have a manager (or else he/she is the CEO). Then, for the manager we configure a many side with the WithMany method. In the end we use the HasForeignKey method to indicate what is the foreign key (which is the ManagerID in the example). That is it.
In order to finish the example I’ve created a database initializer that inserts some data:

public class ExampleInitializer : DropCreateDatabaseIfModelChanges<CompanyContext>
{
  #region Methods
 
  protected override void Seed(CompanyContext context)
  {
    var manager = new Employee
    {
      FirstName = "emp1",
      LastName = "emp1",
    };
    var emp1 = new Employee
    {
      FirstName = "emp1",
      LastName = "emp1",
      Manager = manager
    };
    var emp2 = new Employee
    {
      FirstName = "emp2",
      LastName = "emp2",
      Manager = manager
    };
 
    context.Employees.Add(emp1);
    context.Employees.Add(emp2);
    context.SaveChanges();
  }
 
 #endregion
}

and a console application that run the example:

class Program
{
  static void Main(string[] args)
  {
    Database.SetInitializer(new ExampleInitializer());
 
    using (var context = new CompanyContext())
    {
      var query = context.Employees.Include(e => e.Manager).ToList();
      foreach (var employee in query)
      {
        Console.WriteLine("{0} {1}", employee.EmployeeID, employee.ManagerID);
      }
    }
  }
}

Here is a figure of the output:
Running Output

Summary

Lets sum up, the post includes a running example of how to configure a self reference entity with Code First. I hope it will help you if you get stuck with such a configuration.

Topics:

Published at DZone with permission of Gil Fink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}