Relationships between Entities in Entity Framework 6

Here, you will learn how entity framework manages the relationships between entities.

Entity framework supports three types of relationships, same as database: 1) One-to-One 2) One-to-Many, and 3) Many-to-Many.

We have created an Entity Data Model for the SchoolDB database in the Create Entity Data Model chapter. The following figure shows the visual designer for that EDM with all the entities and relationships among them.

Entity relationships in entity framework

Let's see how each relationship (association) is being managed by entity framework.

One-to-One Relationship

As you can see in the above figure, Student and StudentAddress have a One-to-One relationship (zero or one). A student can have only one or zero addresses. Entity framework adds the Student reference navigation property into the StudentAddress entity and the StudentAddress navigation entity into the Student entity. Also, the StudentAddress entity has both StudentId property as PrimaryKey and ForeignKey, which makes it a one-to-one relationship.

public partial class Student
{
    public Student()
    {
        this.Courses = new HashSet<Course>();
    }
    
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public Nullable<int> StandardId { get; set; }
    public byte[] RowVersion { get; set; }
    
    public virtual StudentAddress StudentAddress { get; set; }
    }
    
public partial class StudentAddress
{
    public int StudentID { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    
    public virtual Student Student { get; set; }
}

In the above example, the StudentId property needs to be PrimaryKey as well as ForeignKey. This can be configured using Fluent API in the OnModelCreating method of the context class.

One-to-Many Relationship

The Standard and Teacher entities have a One-to-Many relationship marked by multiplicity where 1 is for One and * is for Many. This means that Standard can have many Teachers whereas Teacher can associate with only one Standard.

To represent this, the Standard entity has the collection navigation property Teachers (please notice that it's plural), which indicates that one Standard can have a collection of Teachers (many teachers). And the Teacher entity has a Standard navigation property (reference property), which indicates that Teacher is associated with one Standard. Also, it contains the StandardId foreign key (PK in Standard entity). This makes it a One-to-Many relationship.

public partial class Standard
{
    public Standard()
    {
        this.Teachers = new HashSet<Teacher>();
    }
    
    public int StandardId { get; set; }
    public string StandardName { get; set; }
    public string Description { get; set; }
    
    public virtual ICollection<Teacher> Teachers { get; set; }
}

public partial class Teacher
{
    public Teacher()
    {
        this.Courses = new HashSet<Course>();
    }
    
    public int TeacherId { get; set; }
    public string TeacherName { get; set; }
    public Nullable<int> TeacherType { get; set; }
    
    public Nullable<int> StandardId { get; set; }
    public virtual Standard Standard { get; set; }
}

Many-to-Many Relationship

The Student and Course have a Many-to-Many relationship marked by * multiplicity. It means one Student can enroll for many Courses and also, one Course can be taught to many Students.

The database includes the StudentCourse joining table which includes the primary key of both the tables (Student and Course tables). Entity Framework represents many-to-many relationships by not having the entity set (DbSet property) for the joining table in the CSDL and visual designer. Instead it manages this through mapping.

As you can see in the above figure, the Student entity includes the collection navigation property Courses and Course entity includes the collection navigation property Students to represent a many-to-many relationship between them.

The following code snippet shows the Student and Course entity classes.

public partial class Student
{
    public Student()
    {
        this.Courses = new HashSet<Course>();
    }
    
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public Nullable<int> StandardId { get; set; }
    public byte[] RowVersion { get; set; }
    
    public virtual ICollection<Course> Courses { get; set; }
}
    
public partial class Course
{
    public Course()
    {
        this.Students = new HashSet<Student>();
    }
    
    public int CourseId { get; set; }
    public string CourseName { get; set; }
    public System.Data.Entity.Spatial.DbGeography Location { get; set; }
    
    public virtual ICollection<Student> Students { get; set; }
}

Note: Entity framework supports many-to-many relationships only when the joining table (StudentCourse in this case) does NOT include any columns other than PKs of both tables. If the join tables contain additional columns, such as DateCreated, then the EDM creates an entity for the middle table as well and you will have to manage CRUD operations for many-to-many entities manually.

Open EDM in XML view. You can see that SSDL (storage schema) has the StudentCourse entityset, but CSDL doesn't have it. Instead, it's being mapped in the navigation property of the Student and Course entities. MSL (C-S Mapping) has mapping between Student and Course put into the StudentCourse table in the <AssociationSetMapping/> section.

entity relationships in entity framework

Thus, a many-to-many relationship is being managed by C-S mapping in EDM. So, when you add a Student in a Course or a Course in a Student entity and when you save it, it will then insert the PK of the added student and course in the StudentCourse table. So, this mapping not only enables a convenient association directly between the two entities, but also manages querying, inserts, and updates across these joins.