Configure One To One Relationship In Entity Framework Using Code First Approach

Introduction

 
Relationship between tables is defined using foreign keys in a relational database. The foreign key is a column or combination of columns that enforce the relationship between data of two tables. There are three types of relationships:
  1. One to One
  2. One to Many or Many to one
  3. Many to Many
All three types of relationships are supported by the entity framework in the code first approach. In this article, we will cover one relationship between entities.
 
A one-to-one relationship happens when the primary key of one table becomes a foreign key in another table. Entity framework enforces the primary key of the first table should participate in the primary key of the second table. In this relationship, only one record or zero records are present on either side of the tables.
 
Understand One to One relationship
 
To understand the one-to-one relationships, I have created two entities: Employee and EmployeeDetails. One employee record has only one detailed record. Here EmployeeId is the primary key for the Employee table and the same key is present on the primary key and foreign key of the EmployeeDetail table.
 
One to One relationship
 
Through an association, an entity can be related to the other entities in the entity framework. The relation between the entities contains two ends which describe the type of the entity and multiplicity of the type. The two ends of relation can be referred to as the principal role and dependent role.
 
There are two ways to configure one relation between two entities in Entity Framework
 
Using DataAnnotation
 
Entity Framework code first provides a set of data annotation attributes that can be applied to domain classes or the properties of domain classes. ForeignKey Attribute specifies the foreign key for the Navigation property in Entity Framework. As discussed earlier, a relationship in the entity framework always has two ends, a navigation property on each side and an Entity Framework that maps them together automatically by convention. If there are multiple relationships between the two entities, Entity Framework cannot handle the relationships. This is because Entity Framework doesn't know which navigation property map with which properties on another side. InverseProperty attribute can help us to resolve this issue.
 
Example
 
Employee POCO class
  1. [Table("Employee")]  
  2. public partial class Employee  
  3. {  
  4.     [DatabaseGenerated(DatabaseGeneratedOption.None)]  
  5.     public int EmployeeId  
  6.     {  
  7.         get;  
  8.         set;  
  9.     }  
  10.     [Required]  
  11.     [StringLength(50)]  
  12.     public string FirstName  
  13.     {  
  14.         get;  
  15.         set;  
  16.     }  
  17.     [Required]  
  18.     [StringLength(50)]  
  19.     public string LastName  
  20.     {  
  21.         get;  
  22.         set;  
  23.     }  
  24.     [StringLength(50)]  
  25.     public string MiddleName  
  26.     {  
  27.         get;  
  28.         set;  
  29.     }  
  30.     public virtual EmployeeDetail 
  31.     {  
  32.         get;  
  33.         set;  
  34.     }  
  35. }  
EmployeeDetail POCO class:
  1. [Table("EmployeeDetail")]  
  2. public partial class EmployeeDetail  
  3. {  
  4.     [Key, ForeignKey("Employee")]  
  5.     [DatabaseGenerated(DatabaseGeneratedOption.None)]  
  6.     public int EmployeeId  
  7.     {  
  8.         get;  
  9.         set;  
  10.     }  
  11.     [StringLength(10)]  
  12.     public string Gender  
  13.     {  
  14.         get;  
  15.         set;  
  16.     }  
  17.     [StringLength(255)]  
  18.     public string EmailAddress  
  19.     {  
  20.         get;  
  21.         set;  
  22.     }  
  23.     [StringLength(50)]  
  24.     public string PhoneNumber  
  25.     {  
  26.         get;  
  27.         set;  
  28.     }  
  29.     public virtual EmployeeEmployee  
  30.     {  
  31.         get;  
  32.         set;  
  33.     }  
  34. }  
Entity Context class
  1. public partial class EFTestModel: DbContext  
  2. {  
  3.     public EFTestModel(): base("name=entities")  
  4.     {}  
  5.     public virtualDbSet < Employee > Employees  
  6.     {  
  7.         get;  
  8.         set;  
  9.     }  
  10.     public virtual DbSet < EmployeeDetail > EmployeeDetails  
  11.     {  
  12.         get;  
  13.         set;  
  14.     }  
  15.     protected override void OnModelCreating(DbModelBuildermodelBuilder)  
  16.     {}  
  17. }  
In the above example, Employee and EmployeeDetail classes have a one-to-one relation. Here EmployeeId will become the primary key of the Employee table and we have used key and ForeignKey attributes for employeeId property in EmployeeDetail class in order to make primary key and foreign key. In the highlighted text in the above code, we have to pass the Employee entity in ForeignKey attribute of EmployeeDetail class. Thus, Code first creates one to one relation between Employee and EmployeeDetail class using DataAnnotations attributes.
 
To test the above model, I have created a console application and get the first employee and print its details on the screen.
  1. static void Main(string[] args)  
  2. {  
  3.     //Configure One to One Relationship in Entity Framework Using Code First Approach  
  4.     Employee employee;  
  5.     using(var context = newEntityModel.EFTestModel())  
  6.     {  
  7.         employee = context.Employees.FirstOrDefault();  
  8.         Console.WriteLine("Employee Details");  
  9.         Console.WriteLine("Employee Name:" + string.Join(" ", newobject[]  
  10.         {  
  11.             employee.FirstName, employee.LastName  
  12.         }));  
  13.         Console.WriteLine("Employee Email Address:" + employee.EmployeeDetail.EmailAddress);  
  14.     }  
  15.     Console.ReadLine();  
  16. }  
Output
 
run
 
Using Fluent API
 
For conventions of the primary key and foreign key in code first, we can use "Fluent API". Using the "HasKey" method, we can define the primary key. "HasOptional" method is used to make property nullable and the "WithRequired" specifies that an entity must have a corresponding relation entity. Using these two methods of fluent API, we can define a foreign key in code first.
 
We can configure one-to-one relation between Employee and EmployeeDetail using Fluent API by the following code in a model class:
  1. protected override void OnModelCreating(DbModelBuildermodelBuilder)  
  2. {  
  3.     modelBuilder.Entity < Customer > ().HasKey(p => p.CustomerId);  
  4.     modelBuilder.Entity < Customer > ().HasOptional(e => e.CustomerDetail).WithRequired(e => e.Customer);  
  5. }  
The following is the class definition for Customer and CustomerDetail.
  1. [Table("Customer")]  
  2. public partial class Customer  
  3. {  
  4.     [DatabaseGenerated(DatabaseGeneratedOption.None)]  
  5.     public int CustomerId  
  6.     {  
  7.         get;  
  8.         set;  
  9.     }  
  10.     [Required]  
  11.     [StringLength(50)]  
  12.     public string FirstName  
  13.     {  
  14.         get;  
  15.         set;  
  16.     }  
  17.     [Required]  
  18.     [StringLength(50)]  
  19.     public string LastName  
  20.     {  
  21.         get;  
  22.         set;  
  23.     }  
  24.     [StringLength(50)]  
  25.     public string MiddleName  
  26.     {  
  27.         get;  
  28.         set;  
  29.     }  
  30.     public virtual CustomerDetailCustomerDetail  
  31.     {  
  32.         get;  
  33.         set;  
  34.     }  
  35. }  
  36. [Table("CustomerDetail")]  
  37. public partial class CustomerDetail  
  38. {  
  39.     [Key]  
  40.     [DatabaseGenerated(DatabaseGeneratedOption.None)]  
  41.     public int CustomerId  
  42.     {  
  43.         get;  
  44.         set;  
  45.     }  
  46.     [StringLength(255)]  
  47.     public string EmailAddress  
  48.     {  
  49.         get;  
  50.         set;  
  51.     }  
  52.     [StringLength(50)]  
  53.     public string PhoneNumber  
  54.     {  
  55.         get;  
  56.         set;  
  57.     }  
  58.     public virtual CustomerCustomer  
  59.     {  
  60.         get;  
  61.         set;  
  62.     }  
  63. }  
To test the above model, I have created a console application and the first employee is to get and the details are printed on the screen.
  1. static void Main(string[] args)  
  2. {  
  3.     //Configure One to One Relationship in Entity Framework Using Code First Approach  
  4.     Customer c;  
  5.     using(var context = newEntityModel.EFTestModel())  
  6.     {  
  7.         c = context.Customers.FirstOrDefault();  
  8.         Console.WriteLine("Customer Details");  
  9.         Console.WriteLine("Customer Name:" + string.Join(" ", newobject[]  
  10.         {  
  11.             c.FirstName, c.LastName  
  12.         }));  
  13.         Console.WriteLine("Customer Email Address:" + c.CustomerDetail.EmailAddress);  
  14.     }  
  15.     Console.ReadLine();  
  16. }  
Output
 
Output
 

Summary

 
This article helps us to learn how to configure one-to-one relation between entities in the code first approach using data annotation or fluent API.
 
In the next article, we will learn how to configure one too many relations in entity framework in the code first approach.