The InverseProperty informs the EF, which navigational property it relates to on the other side of the relationship. If two entities have a single relationship between them, the EF convention correctly identities them. But it fails when there are multiple relationships between entities. In such cases, we use the InverseProperty
to help the EF correctly identify the relationship.
Table of Contents
Default Convention
A relationship in the Entity Framework always has two endpoints. Each end must return a navigational property that maps to the other end of the relationship. you can read about it from the tutorial relationships in Entity Framework. The Entity Framework by convention detects this relationship and creates the appropriate Foreign Key column.
Consider the following model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Employee { public int EmployeeID { get; set; } public string Name { get; set; } public int DepartmentID { get; set; } public Department Department { get; set; } } public class Department { public int DepartmentID { get; set; } public string Name { get; set; } public virtual ICollection<Employee> Employees { get; set; } } |
In the above example, we have employee belonging to a particular department. The default convention automatically detects the relationship and creates the DepartmentID
foreign key column in the Employee table.
Multiple Relations
The employee and department is a single relationship. What if the employee belongs to multiple departments ?. Let us take the example of flight & airports. Flight departing from one airport and arrives at another. So the flight has multiple relationships with the Airport
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Flight { public int FlightID { get; set; } public string Name { get; set; } public Airport DepartureAirport { get; set; } public Airport ArrivalAirport { get; set; } } public class Airport { public int AirportID { get; set; } public string Name { get; set; } public virtual ICollection<Flight> DepartingFlights { get; set; } public virtual ICollection<Flight> ArrivingFlights { get; set; } } |
The DepartngFlights
property must map to DepartureAirport
property in the airport model and ArrivingFlights
property must map to ArrivalAirport property
.
The default Convention in EF fails to detect such relationships. There is no way EF can deduce which navigational property maps to which property on the other end. It will assume that these are four different relationships and creates the four columns in the Flight table as shown in the image below.
Using InverseProperty
The InverseProperty
data annotation attribute can solve the above problem.
We apply the InverseProperty
to a property on any one side of the relationship. We specify the related navigational property from the other end of the relationship as its argument.
The Airport class after applying the InverseProperty
is as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Airport { public int AirportID { get; set; } public string Name { get; set; } [InverseProperty("DepartureAirport")] public virtual ICollection<Flight> DepartingFlights { get; set; } [InverseProperty("ArrivalAirport")] public virtual ICollection<Flight> ArrivingFlights { get; set; } } |
Now the EF matches the relationship correctly and creates only two fields as shown in the image below.
You can apply InverseProperty
on the Flight instead of the airport as shown below. Both will result in the same output
1 2 3 4 5 6 7 8 9 10 11 | public class Flight { public int FlightID { get; set; } public string Name { get; set; } [InverseProperty("DepartingFlights")] public Airport DepartureAirport { get; set; } [InverseProperty("ArrivingFlights")] public Airport ArrivalAirport { get; set; } } |
References
Read More
- Entity Framework Tutorial
- Configure the Entity Data Model
- Conventions in Entity Framework
- Fluent API in Entity Framework
- ForeignKey Attribute
- Relationships in Entity Framework
- One to one relationship in Entity Framework
- One to Many relationships in Entity Framework
- Many to Many relationships in Entity Framework