Back to: ASP.NET Core Tutorials For Beginners and Professionals
Self-Referencing Relationship in Entity Framework Core
In this article, I am going to discuss How to Configure Self-Referencing Relationships in Entity Framework Core using Fluent API with Examples. Please read our previous article, where we discussed How to Configure Many-to-Many Relationships in EF Core using Fluent API.
Self-Referencing Relationship in Entity Framework Core
A self-referencing relationship in Entity Framework Core (EF Core) occurs when an entity has a relationship with instances of the same entity type. This is useful for scenarios where an entity is related to other entities of the same type, such as in hierarchical structures like organizational charts or comments on a post.
Similar to a self-referencing relationship in a relational database, an entity can have a relationship with instances of the same entity type. For example, an Employee entity can have a Manager navigation property that points to another Employee.
Let’s say we have an entity called Employee that has a self-referencing relationship to represent a manager-subordinate relationship:
namespace EFCoreCodeFirstDemo.Entities { public class Employee { public int EmployeeId { get; set; } public string? Name { get; set; } public int? ManagerId { get; set; } public Employee? Manager { get; set; } public List<Employee>? Subordinates { get; set; } } }
In the above example, an Employee entity has a Manager navigation property that points to another Employee, representing the manager of the current employee representing the one-to-one relationship. Additionally, it has a collection navigation property called Subordinates to represent the employees who report to the current employee representing the one-to-many relationships.
using Microsoft.EntityFrameworkCore; namespace EFCoreCodeFirstDemo.Entities { public class EFCoreDbContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { //Configuring the Connection String optionsBuilder.UseSqlServer(@"Server=LAPTOP-6P5NK25R\SQLSERVER2022DEV;Database=EFCoreDB;Trusted_Connection=True;TrustServerCertificate=True;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { //Configuring the Employee Entity to Represent Self-Referential Relationships modelBuilder.Entity<Employee>() .HasOne(e => e.Manager) // Employee has one Manager .WithMany(e => e.Subordinates) // Manager has many Subordinates .HasForeignKey(e => e.ManagerId) // Foreign key in Employee table .OnDelete(DeleteBehavior.Restrict); // Optional: Configure delete behavior } public DbSet<Employee> Employees { get; set; } } }
In this configuration, we use the HasOne and WithMany methods to define the self-referencing relationship between Employee and himself. The HasForeignKey method specifies the foreign key property (ManagerId) in the Employee table. You can also specify the delete behavior using the OnDelete method, which determines what happens to related entities when an entity is deleted.
Note: Before Proceeding further, let us delete the EFCoreDB database using SSMS and Migration folder from our project.
With the above changes in place, open Package Manager Console and Execute the following add-migration and update-database commands. You can give any name to your migration. Here, I am giving EFCoreDBMig1. The name that you are giving it should not be given earlier.
Now, if you verify the database, you should see the following.
Next, modify the Main method of the Program class as follows.
using EFCoreCodeFirstDemo.Entities; namespace EFCoreCodeFirstDemo { internal class Program { static void Main(string[] args) { try { using var context = new EFCoreDbContext(); //Create a Manager Employee mgr = new Employee() { Name = "Pranaya"}; context.Add(mgr); context.SaveChanges(); Console.WriteLine("Manager Added"); Employee emp1 = new Employee() { Name ="Hina", ManagerId = 1}; context.Add(emp1); Employee emp2 = new Employee() { Name ="Ramesh", ManagerId = 1 }; context.Add(emp2); context.SaveChanges(); Console.WriteLine("Employees Added"); //List of Employee including Manager var listOfEmployees = context.Employees.ToList(); Console.WriteLine("List of Employees"); foreach (var emp in listOfEmployees) { Console.WriteLine($"\tEmployee ID:{emp.Name}, Name:{emp.Name}"); } //List of Subordinates working under Manager whose Id = 1 var Manager = context.Employees.Find(1); if( Manager != null ) { Console.WriteLine($"\nList of Employees working under Manager : {Manager.Name}"); if (Manager.Subordinates != null) { foreach (var emp in Manager.Subordinates) { Console.WriteLine($"Employee ID:{emp.Name}, Name:{emp.Name}"); } } } Console.ReadKey(); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); ; } } } }
Output:
In the next article, I am going to discuss Entity Configurations using Entity Framework Core Fluent API with Examples. In this article, I explain How to Configure Self-Referencing Relationships in Entity Framework Core using Fluent API with Examples. I hope you enjoyed this article.