Introduction

Today I will share some of the information for creating many-to-many mappings using the Code First Approach. Using the Code First approach we follow mostly the case when our database is already created or with our DomainModel classes, we will create a database.

Creating Mapping

There is sometimes a situation where we need to create a many-to-many relationship. To do that we create a bridge table that holds the primary keys of both of the tables involved in the many-to-many relationship.



Figure 1: Creating Many-to-Many Mapping

In the Code First Approach, while we creating such a relationship, we create entries for both sides in an ICollection Objects here. First create a Console Application with a many-to-many relationship.



Figure 2: Create Application

Then install a Nuget package Entityframework as Figure 3.



Figure 3: Install Nuget Package

Now add a connection string in the App.config file as in the following:

  1. < connectionStrings >
  2. < add name = "ConnString" connectionString = "server=****;database=MVCSample;uid=**;password=***;Connection Timeout=3"
  3. providerName = "System.Data.SqlClient" / >
  4. < /connectionStrings>
Then we create the classes for the model (DB entities) as in the following:
  1. public class Vendor
  2. {
  3. public Vendor()
  4. {
  5. VendorProducts = new List < Product > ();
  6. }
  7. public virtual int VendorId
  8. {
  9. get;
  10. set;
  11. }
  12. public virtual string VendorName
  13. {
  14. get;
  15. set;
  16. }
  17. public virtual ICollection < Product > VendorProducts
  18. {
  19. get;
  20. set;
  21. }
  22. }
  23. public class Product
  24. {
  25. public Product()
  26. {
  27. ProductVendors = new List < Vendor > ();
  28. }
  29. public virtual int ProductId
  30. {
  31. get;
  32. set;
  33. }
  34. public virtual string ProductName
  35. {
  36. get;
  37. set;
  38. }
  39. public virtual ICollection < Vendor > ProductVendors
  40. {
  41. get;
  42. set;
  43. }
  44. }
Then we will write the SuperMArketContext class that will be inherited by the DBContext class as in the following:
  1. public class SuperMarketContext: DbContext
  2. {
  3. public DbSet < Product > Product
  4. {
  5. get;
  6. set;
  7. }
  8. public DbSet < Vendor > Vendor
  9. {
  10. get;
  11. set;
  12. }
  13. public SuperMarketContext(): base("ConnString") {}
  14. }
You will see in this Context class that first we declare two properties as in the following. Those properties will return a Dbset of those objects.
  1. public DbSet<Product> Product { get; set; }
  2. public DbSet<Vendor> Vendor { get; set; }
While in the contructor we provide the Connectionstring that we define in the App.config file.

Now if we run the sample application it will create the MVCSample database (as specified in the config) and the table will be created but the column name is not as per our expectations. See the figure below.



Figure 4: Solution Explorer

So we can solve this problem by overriding the OnModelCreating method and mapping using the Code First Fluent API as in the following:
  1. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  2. {
  3. modelBuilder.Entity < Vendor > ()
  4. .HasMany(v = > v.VendorProducts)
  5. .WithMany(p = > p.ProductVendors)
  6. .Map(
  7. m = >
  8. {
  9. m.MapLeftKey("VendorId");
  10. m.MapRightKey("ProductId");
  11. m.ToTable("VendorProduct");
  12. });
  13. }
In this mapping we start with the Vendor (alternatively we can start with the Products).

So if you run the code you will get the tables generated depending on your specified column name.

  1. static void Main(string[] args)
  2. {
  3. using(SuperMarketContext db = new SuperMarketContext())
  4. {
  5. Product P1 = new Product();
  6. P1.ProductName = "Dell products";
  7. Vendor V1 = new Vendor();
  8. V1.VendorName = "Vivek";
  9. V1.VendorProducts.Add(P1);
  10. db.Vendor.Add(V1);
  11. db.SaveChanges();
  12. Console.ReadKey();
  13. }
  14. }
The tables will be generated like this:



Figure 5: Output

So in this way you can create a many-to-many relationship with the Code First Approach very easily.

Thanks.