Introduction
This article allows us to understand how to setup Many to Many relationship entities manually by coding. The same can be done easily using EF designer, but this is a hook about what is going on in the backend.
Using the Code
Create a new MVC4 Project.
Let’s quickly create a Model class, say Student.cs. We will have a simple realtime structure created
so that it is easy for us to understand.
public class Student
{
[Key]
public int student_id {get; set;}
public string student_name {get; set;}
public List courses {get; set;}
}
public class Course
{
[Key]
public int course_id {get; set;}
public string course_name {get; set;}
public List students {get; set;}
}
OK, this looks quite familiar. We created a Student
class which can be associated with multiple courses e.g.,
say Student Harry is interested in multiple technologies like ASP.NET, SQL Server, MVC 4, EF, etc.
- Student: Harry
- Course : ASP.NET
- Course : SQL Server
- Course : MVC 4
- Course : EF
Now, let’s explore the Course
class. This class references multiple students associated with one course, e.g., say Harry, Jerry, Kerry are the three students and they are all learning MVC 4.
- Course: MVC 4
- Student : Harry
- Student : Jerry
- Student : Karry
Pretty simple, isn’t it?
We have our basic classes ready, and they are associated with each one of them a with many to many relation.
Next step: Our next goal is to let EF know that this needs to be created and associated, and to achieve this, let’s jump into our DB Context class. Let's create a DB Context class and write this code into it.
public class StoreDBContext : DbContext
{
public StoreDBContext() : base("DemoDBConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity()x
.HasMany(c => c.courses)
.WithMany(s => s.students)
.Map (mc =>
{
mc.ToTable("StudentCourse");
mc.MapLeftKey("course_id");
mc.MapRightKey("student_id");
});
}
public DbSet Students { get; set; }
public DbSet Courses { get; set; }
}
In the above code, we have created a SQL DB connection string in web.config, and this has been referenced. When EF triggers and creates a Schema using our Model, it will know that it has to create a new intermediate table StudentCourse with reference keys from the Student and Course tables.
Now let’s move and try to seed some data into the Student and Course tables, and see how EF manages to store the data automatically in the StudentCourse table.
Create another class within our StoreDBContext
class:
public class CustomDatabaseInitalizer : DropCreateDatabaseIfModelChanges
{
protected override void Seed(StoreDBContext context)
{
seedStudCourseData();
}
public void seedStudCourseData()
{
StoreDBContext db = new StoreDBContext();
Student s = new Student();
List crsLst = new List();
crsLst.Add(new Course { course_name = "MVC4" });
crsLst.Add(new Course { course_name = "WCF" });
s.student_name = "Harry";
s.courses = crsLst;
db.Students.Add(s);
db.SaveChanges();
}
}
We have created a class CustomDatabaseInitalizer
which inherits DropCreateDatabaseIfModelChanges
. That means, whenever we do some changes in our Model structures we want to drop an entire database and recreate it. Now when the database is created and empty, we will seed some data into the Student and Course tables. The seedStudCourseData()
method creates a Student with name "Harry" and assigns two Courses to him: MVC and WCF.
One last change which we should make sure we do is to Trigger the CustomDatabaseInitalizer()
process when our application starts. To do this, we will
edit the global.asax.cs file and add this line of code in the Application_Start()
method:
System.Data.Entity.Database.SetInitializer(new CustomDatabaseInitalizer());
All done. You are ready to go. Build your application and you will see the Database Schema is created with three tables: Student, Course, and StudentCourse. Because we told EF to create a Relationship table between Students and Courses, it does that while creating a basic schema.
The data will automatically be added to the StudentCourse table whenever we add a student with existing/new courses.
Points of Interest
It is quite interesting that EF is intelligent enough to decide a junction table and add references automatically when there are entries created in the Student table.