Snowburnt
Snowburnt

Reputation: 6922

Many to many relationship in Entity Framework

I set up a many to many relationship like this (removing all the irrelevant properties):

public class Makes
{
  [Key]
  public int MakeId { get; set; }

  public ICollection<KeyWords> KeyWords {get; set;}
}

public class KeyWords 
{
   public KeyWords()
   {
       Makes = new HashSet<Makes>();
   }

   [Key]
   public int KeyWordsId { get; set;}
   public string KeyWord { get; set;}
}

And then in the context definition:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<KeyWords>().HasMany(w => w.Makes).WithMany(kw => kw.KeyWords).Map(
           m =>
           {
                m.MapLeftKey("KeyWords_KeyWordsID");
                m.MapRightKey("Makes_MakesID");
                m.ToTable("MakesKeyWords");
            });

        base.OnModelCreating(modelBuilder);
    }

When I step through the database seeding, it looks like the entity is created correctly when I create some Makes and create some key words and then add some keywords to the makes. I'm able to navigate between the two entities just fine using the watch.

After the database initialization is complete, I look at the database and it looks like all of the data is there. However, when I go to actually display the keywords in the view, the Makes that I KNOW I assigned a keyword to have a count of 0:

@if (Model != null)
{
    Foreach(models.Makes item in model.Makes)
    {
        if (item.KeyWords.Count > 0) 
                {
                    <div class="KeyWords">
                    @foreach (Models.KeyWords kw in item.KeyWords)
                    {
                        <span class="KeyWord">@kw.KeyWord</span>
                    }
                    </div>
                }
     }
}

Nothing happens, the keywords aren't being associated with the makes anymore.

What am I missing?

Thanks!

Upvotes: 1

Views: 264

Answers (1)

Slauma
Slauma

Reputation: 177133

Either mark your navigation property as virtual to enable lazy loading...

public virtual ICollection<KeyWords> KeyWords {get; set;}

...or use Include when you load the makes (eager loading):

var makes = context.Makes.Include(m => m.KeyWords).ToList();

(You need using System.Data.Entity; in your code file for the lambda version of Include.)

Upvotes: 1

Related Questions