How associations are mapped when using Code First with Entity Framework

Mapping single class with a table was bit easy and fun. Next should be mapping associations, first I will try to map a simple one, using our existing application code. A person can have multiple email addresses.

So here is the modified code for person


    public class PersonItem
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Gender { get; set; }
        public Nullable<DateTime> BirthDate { get; set; }

        public virtual ICollection<EmailItem> Emails { get; set; }

        public PersonItem() { this.Emails = new List<EmailItem>(); }
    }

Then I created the required EmailItem class, with relevant mapping configurations.


    public class EmailItem
    {
        public int Id { get; set; }
        public string Address { get; set; }
        public string Label { get; set; }
    }

    class EmailItemConfiguration : EntityTypeConfiguration<EmailItem>
    {
        public EmailItemConfiguration()
        {
            // table
            this.ToTable("email_addresses");

            //primary key
            this.HasKey(t => t.Id);

            this.Property(t => t.Id)
                .HasColumnName("email_id")
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
                
            this.Property(t => t.Address)
                .HasColumnName("email_address")
                .HasMaxLength(256);

            this.Property(t => t.Label)
                .HasColumnName("email_type")
                .HasMaxLength(50)
                .IsRequired();            
        }
    }

Made some changes in context related class as below.

    class BoxContext : DbContext
    {
        public DbSet<PersonItem> PersonItems { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new PersonItemConfiguration());
            modelBuilder.Configurations.Add(new EmailItemConfiguration());

            base.OnModelCreating(modelBuilder);
        }
    }

Then just attached an email to a person in our test as below


    class ContextTest
    {
        public void CreateDatabaseTest()
        {
            using (var context = new BoxContext())
            {
                PersonItem person = new PersonItem();

                person.FirstName = "Zafar";
                person.LastName = "Iqbal";

                EmailItem email = new EmailItem();
                email.Address = "ziqbalbh" + "@" + "gmail.com";
                email.Label = "Personal";

                person.Emails.Add(email);

                context.PersonItems.Add(person);

                context.SaveChanges();
            }
        }
    }

Hmm, lets look at the schema which is now generated after all these changes.

association mapping

look there, table for holding emails has been generated, and it has been linked to people table too. A foreign key is automatically generated, although the name is not quite to our liking. Lets look at how to do that. Just make following changes in person configuration class, and you will have what you want.


            this.HasMany(p => p.Emails)
                .WithRequired()
                .Map(t => t.MapKey("person_id"));                

One thought on “How associations are mapped when using Code First with Entity Framework

Leave a Reply