Introduction

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.

How to Configure a Self Reference in Code First

Self Reference Scenarios

There are a lot of scenarios where 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 add a foreign key in the table that points 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. Let's 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, let's 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 indicates 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 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 runs 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

Let's 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.

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"