I use EF Code First and have a problem in n-n relationship, assume we have a singer that sing in some genres, so we need this models: Artist, Genre, and ArtistsGenres, I define Models as following:
This is My Artist Model:
public class Artist
{
public long Id { get; set; }
public string Name { get; set; }
public ICollection<Genre> Genres { get; set; }
}
And My Genre Model:
public class Genre
{
public long Id { get; set; }
public string Title { get; set; }
public ICollection<Artist> Artists { get; set; }
}
And my context class:
public class MusicDB : DbContex
{
public DbSet<Artist> Artists { get; set; }
public DbSet<Genre> Genres { get; set; }
public DbSet<ArtistsGenres> ArtistsGenres { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Artist>()
.HasMany(a => a.Genres)
.WithMany(g => g.Artists)
.Map(model => {
model.ToTable("ArtistsGenres");
model.MapLeftKey("Artist_Id");
model.MapRightKey("Genre_Id");
});
base.OnModelCreating(modelBuilder);
}
}
But there is not any relationship between Artists and Genres when MVC generate views automatically.
For example, I need to change Genres of an Artist in edit view, in Create view I can set Genres for an Artist, or in Index View I want show genres for each Artist. But there isn't any generation for Genres in relation to Artist when MVC generate views automatically.
I know I can access both Genres and Artists from both side but I am interesting in MVC automatically generate views as we want: for ex: for each artist show related Genres.
How can I do this? Is my model correct? Is this true for any (n to n) relation that needs ICollection on both side? Or do I need some elements in overriding of OnModelCreating
method in context class, for example something like this:
modelBuilder.Entity<Artist>()
.HasMany(a => a.Genres)
.WithMany(g => g.Artists);
Please help me, I don't know the exact implementation of NtoN relationship.
You haven't to create a separate Model
for association between to models in a many-to-many relationship. Really the ArtistsGenres
is not necessary. So, remove it, and you just have to change your modelBuilder
to this one:
modelBuilder.Entity<Artist>()
.HasMany(c => c.Genres)
.WithMany(x => x.Artists)
.Map(a => {
a.ToTable("ArtistsGenres");
a.MapLeftKey("ArtistId");
a.MapRightKey("GenreId");
});
It will use the ArtistsGenres
table to map a many-to-many relationship between Artists
table and
Genres
table automatically.
Note: When you define the ArtistsGenres
model, EF will not look at it as a relationship,
because you tell him that Hey EF, I have another model named ArtistsGenres
! Please manage it for me!!!
Your new entities and dbcontext will be these:
public class Artist {
public long Id { get; set; }
public string Name { get; set; }
public ICollection<Genre> Genres { get; set; }
}
public class Genre {
public long Id { get; set; }
public string Title { get; set; }
public ICollection<Artist> Artists { get; set; }
}
public class MusicDB : DbContex {
public DbSet<Artist> Artists { get; set; }
public DbSet<Genre> Genres { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Artist>()
.HasMany(c => c.Genres)
.WithMany(x => x.Artists)
.Map(a => {
a.ToTable("ArtistsGenres");
a.MapLeftKey("ArtistId");
a.MapRightKey("GenreId");
});
}
Let me know if you have any questions or need clarifications on any part.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With