When using Entity Framework Code First approach, there are actually three ways to define foreign keys. In this post let’s explorer these different ways with some examples (Please note here I am not going to cover the basics of EF, assuming you have some knowledge in Entity Framework.) . Before starting off with the code, first let’s have a quick look at the mentioned three different ways.
First way is pretty much straight forward. That is when you add a navigation property, EF it self will create a foreign key relationship. The second one is using Data Annotations. The last would be using Fluent API.
Now let's see all these in action. Please consider the following two entity classes.
public class Department
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
}
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Department Department { get; set; }
}
Here I have two classes which are “Department” and “Employee”. In “Employee” class, I have a navigation property named “Department” which is of type “Department”. So here what I says is Employee is belonging to a Department.
I have the following “MyContext” class which inherits from DbContext.
public class MyContext : DbContext
{
public DbSet<Department> Departments { get; set; }
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
There in my overrided OnModelCreating method, I am saying that I don’t want to pluralize the table names when tables are created in EF. (You can basically ignore that particular line of code, as it has nothing to with the topic today).
Now in my Main method, I am writing the following code to add some data to “Department” table, so the tables will get generated.
static void Main(string[] args)
{
using (MyContext context = new MyContext())
{
context.Departments.Add(new Department() { DepartmentName = "Microsoft Visual Studio" });
context.SaveChanges();
}
}
Through Navigation Property |
In the “Employee” table, you can see there is a foreign key created named “Department_DepartmentId”. So that is the first way.
Now let’s have a look at defining the foreign key using Data Annotations.
For that, I am going to modify the “Employee” class as follows.
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DepartmentId { get; set; }
[ForeignKey("DepartmentId")]
public Department Department { get; set; }
}
Here I have defined a property of type int named “DepartmentId”. And I have annotated my “Department” property saying that Foreign key is newly added “DepartmentId”. I am deleting the previous database and running the program back again. Now I can see the following database structure.
Through Data Annotations |
In “MyContext” class I am modifying the OnModelCreating() method as follows and I am removing my Data Annotations in the "Department" class.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Employee>()
.HasRequired(e => e.Department)
.WithMany()
.HasForeignKey(e => e.DepartmentId);
}
Again I am deleting the previous database and running the program back again. When I examine the created the database now, It’s as same as the previous method.
Through Fluent API |
So hope you find this post helpful. I am uploading the sample to my OneDrive. Do check it out and appreciate your feedback.
Happy Coding.
Regards,
Jaliya
Great explanation! Thank You!
ReplyDeleteVery clear and short explanation. Helped me a lot.
ReplyDeleteYou are very clear in your explanation. Thank you.
ReplyDeleteThank YOU. Very Nice
ReplyDeleteUseful - thanks
ReplyDeleteThanks for your explanation. Its helpful. Please help me to understand the last example. I want to clear my confusion.
ReplyDeletemodelBuilder.Entity()
ReplyDelete.HasRequired(e => e.Department)
.WithMany()
.HasForeignKey(e => e.DepartmentId);
Error DepartmentId is not found as part of Employee and no extension method....
WOW... I am surprised Julie Lerman copied her stuff from you. What books do you have out on EF so that I can buy yours instead of hers ?
ReplyDeleteMuchas gracias, me ha sito muy útil.
ReplyDelete