You can do this by specifying the relationship explicitly using the Fluent API. Override the OnModelCreating()
method of your DbContext
class, and in your override specify the details of the mapping table like this:
class MyContext : DbContext
{
public DbSet<Currency> Currencies { get; set; }
public DbSet<Country> Countries { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Country>()
.HasMany(c => c.Currencies)
.WithMany() // Note the empty WithMany()
.Map(x =>
{
x.MapLeftKey("CountryId");
x.MapRightKey("CurrencyId");
x.ToTable("CountryCurrencyMapping");
});
base.OnModelCreating(modelBuilder);
}
}
Note that - in my quick test anyway - you will have to Include()
the Currencies property when loading the EF object to have the list populated:
var us = db.Countries
.Where(x => x.Name == "United States")
.Include(x=>x.Currencies)
.First();
EDIT
If you really want to do everything with Data Annotations, and not use Fluent at all, then you can model the join table explicitly as pointed out elsewhere. There are various usability disadvantages of this approach, though, so it seems the Fluent method is the best approach.
class Country
{
public int Id { get; set; }
public virtual ICollection<CountryCurrency> CountryCurrencies { get; set; }
}
class Currency
{
public int Id { get; set; }
}
class CountryCurrency
{
[Key, Column(Order=0)]
public virtual int CountryId { get; set; }
[Key, Column(Order=1)]
public virtual int CurrencyId { get; set; }
public virtual Country Country { get; set; }
public virtual Currency Currency { get; set; }
}