Search code examples
c#asp.net-mvc-4database-migrationentity-framework-4.3

How to use Database Migrations and EF 4.3 with a code first approach to create relationship tables?


I have been trying to get a handle on using MVC 4.0 with EF 4.3 and Database Migrations as introduced by Scott Gu at Tech Days and have run into an issue with the database that is created when a many to many relationship exists.

http://channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2364 starts at 21:14

Included are the snippets of code that were used to generate the database as shown in the image below.

public class Trip    {
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime Begin { get; set; }
    public DateTime End { get; set; }
    public Location HomeCountry { get; set; }
    //public IList<Location> Itinerary { get; set; }

    public ICollection<Location> Itinerary { get; set; }

    public Trip()
    {
        this.Itinerary = new HashSet<Location>();
    }
}


public class Location
{
    public int ID { get; set; }
    public string Name { get; set; }

    public ICollection<Trip> Trips { get; set; }

    public Location()
    {
        this.Trips = new HashSet<Trip>();
    }

}

This was the resulting database. (I would have posted an image, but I am unable to post an image, still being a new user)

Tables
  Locations
    PK ID      (int)
       Name    (varchar)
       Trip_ID (int)
  Trips
    PK ID             (int)
       Name           (varchar)
       Begin          (datetime)
       End            (datetime)
       HomeCountry_ID (int)

I guess I would have expected a third relationship table to be created for the many to many relationship between Locations and Trips (many Locations can apply to many Trips), versus, adding the Trip_Id column to the Locations table. Does anyone know what I did wrong here? Is there a way to get the data base automation to create these tables correctly?

Thanks in advance for all of your help!

Update: I found the following link, but I am still unable to get this to work using EF 4.3. I also edited my code snippets to reflect the following post.

http://www.codeproject.com/Articles/234606/Creating-a-Many-To-Many-Mapping-Using-Code-First


Solution

  • I was finally able to get the tables created correctly, using the link i added to my updated question, but still not really sold on the solution. To my Db Context class I added the method [protected override void OnModelCreating(DbModelBuilder modelBuilder)].

    public class MyTesterContext : DbContext
    {
        public MyTesterContext () : base("name=MyTesterContext ")
        {
        }
    
        public DbSet<Trip> Trips { get; set; }
        public DbSet<Location> Locations { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Trip>().
              HasMany(t => t.Itinerary).
              WithMany(l => l.Trips).
              Map(
               m =>
               {
                   m.MapLeftKey("TripID");
                   m.MapRightKey("LocationID");
                   m.ToTable("TripLocations");
               });
        }
    
    }
    

    The new database now looks like the following:

    Tables
      Locations
        PK ID      (int)
           Name    (varchar)
      TripLocations
           TripID     (int)
           LocationID (int)
      Trips
        PK ID             (int)
           Name           (varchar)
           Begin          (datetime)
           End            (datetime)
           HomeCountry_ID (int)
    

    In the code project discussion it says:
    http://www.codeproject.com/Articles/234606/Creating-a-Many-To-Many-Mapping-Using-Code-First

    So we have a small problem with existing relation tables. We can solve the problem by overriding the OnModelCreating method and adding the mapping using the Code First Fluent API.

    Since I did not have an existing relation table, I honestly did not think this step would be required, but I have been unable to find any other way to get this to create the proper table structure. Hopefully as I become more familiar with the technology, I can find a way around requiring the need to override the OnModelCreating method.