2011-11-22 10 views
10

utilizzare EF Codice Prima e hanno un problema in relazione nn, supponiamo di avere un cantante che cantare in alcuni generi, così abbiamo bisogno di questo modelli: artista, genere, e ArtistsGenres, definisco modelle come segue:Come funziona la relazione n-n del modello in primo luogo per generare automaticamente le viste generate correttamente?

Questo è il mio artista Modello:

public class Artist 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<Genre> Genres { get; set; } 
} 

E il mio genere Modello:

public class Genre 
{ 
    public long Id { get; set; } 
    public string Title { get; set; } 
    public ICollection<Artist> Artists { get; set; } 
} 

E la mia classe del contesto:

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); 
     } 
} 

Tuttavia, non vi è alcuna relazione tra Artisti e Generi quando MVC genera automaticamente le viste.

Ad esempio, ho bisogno di cambiare Generi di un artista in visualizzazione di modifica, in Crea vista Posso impostare Generi per un artista, o in Vista indice Voglio generi di spettacoli per ogni artista. Ma non esiste alcuna generazione di Generi in relazione all'artista quando MVC genera automaticamente le viste.

So che posso accedere sia a Generi che a Artisti da entrambi i lati, ma sono interessante in MVC generare automaticamente le visualizzazioni come vogliamo: per esempio: per ogni genere di genere.

Come posso fare questo? Il mio modello è corretto? È vero per qualsiasi relazione (da n a n) che richiede ICollection da entrambe le parti? O ho bisogno di alcuni elementi in prioritario della OnModelCreating metodo nella classe del contesto, per esempio qualcosa di simile:

modelBuilder.Entity<Artist>() 
    .HasMany(a => a.Genres) 
    .WithMany(g => g.Artists); 

Please help me, non so l'esatta applicazione della relazione Nton.

risposta

0

La connessione tra artista e generi è la ArtistsGenre.

Così artista containt: ID, Nome

E Genere contiene: ID, Titolo

E ArtistsGenre contiene: ID artista, ID genere

12

di non avere creare uno separato per l'associazione tra i modelli in una relazione molti-a-molti. Davvero il ArtistsGenres non è necessario. Quindi, rimuoverlo, e basta cambiare la vostra modelBuilder a questo:

modelBuilder.Entity<Artist>() 
    .HasMany(c => c.Genres) 
    .WithMany(x => x.Artists) 
    .Map(a => { 
     a.ToTable("ArtistsGenres"); 
     a.MapLeftKey("ArtistId"); 
     a.MapRightKey("GenreId"); 
    }); 

Si utilizzerà il tavolo ArtistsGenres per mappare una relazione molti-a-molti tra Artists tavolo e Genres tavolo automaticamente.

Nota: Quando si definisce il modello ArtistsGenres, EF non guardare ad esso come un rapporto, perché gli dici che Hey EF, ho un altro modello denominato ArtistsGenres! Per favore gestiscilo per me !!!

Le nuove entità e DbContext saranno questi:

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"); 
     }); 

} 

fatemi sapere se avete domande o bisogno di chiarimenti su qualsiasi parte.

+0

il tuo diritto, ma questa soluzione crea solo un tavolo ArtistsGenres automaticamente e tutti i miei problemi di acciaio non sono risolti, non c'è alcuna relazione tra genere e artista in nessuna vista. – Saeid

+0

Modifica la mia domanda con la tua risposta – Saeid

+0

Se vuoi dire che 'MVC' genera' View's con l'associazione dei modelli automaticamente, per quanto ne so, non può! e dovresti creare i tuoi template 'T4'. Intendevi questo? Se sì, dovresti cambiare la tua Q, in caso contrario, per favore spiega di più il tuo scopo. Cordiali saluti –

0

Il problema è che non si carica esplicitamente la raccolta Genres della classe artista e non si consente a EF di intercettare l'accesso alla proprietà non dichiarandolo come virtual.

public class Artist 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Genre> Genres { get; set; } 
} 

Poi, quando è necessario accedere artista e dei relativi generi è necessario desiderosi caricarli

var artist = db.Artists.Include(a => a.Genres) 
     .Where(a => a.Name == "Foo").SingleOrDefault() 

Rendere la Genres proprietà virtuale permetterà EF per carico pigro della collezione, se non l'avete fatto ansiosi caricarlo.

+0

Penso che abbiamo una visione diversa della domanda, so che posso accedere a Generi o Artisti da entrambe le parti, ma sono interessante in MVC generare automaticamente le visualizzazioni come vogliamo: per esempio: per ogni artista mostra i generi correlati – Saeid

1

Ti suggerisco di seguire l'approccio più semplice della creazione di un altro modello ArtistGenre e lasciare che EF capisca la relazione da sola. Crea la tabella come di seguito.

Dopodiché si aggiungerà un'altra tabella al database con il nome precedente con due proprietà chiave fori e una chiave primaria.

Ora è possibile eseguire le query su questa tabella. Dire

var artist = myContext.ArtistGenre.where(g = g.GenreId == 1).ToList(); 

Ora, l'artista conserva tutti gli artisti in Genere con Id = 1. Puoi fare il vice-versa anche per Genres in modo simile.

Spero che aiuti !!

Problemi correlati