2013-10-28 8 views
19

Sto provando a fare un test in EF, creando una relazione molte a molte, perché mappando sempre One to One o One to Many, ho un esempio in internet per prova, l'esempio sta lavorando per i registri di inserimento, ma non riesco a leggere i registriMappare molte a molte relazioni nel codice del framework entità prima

Ecco le mie classi, non so che cosa è HashSet, ottengo questo codice nel sito

public class Person 
{ 
    public int PersonId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public ICollection<Course> CoursesAttending { get; set; } 

    public Person() 
    { 
     CoursesAttending = new HashSet<Course>(); 
    } 
} 

public class Course 
{ 
    public int CourseId { get; set; } 
    public string Title { get; set; } 

    public ICollection<Person> Students { get; set; } 

    public Course() 
    { 
     Students = new HashSet<Person>(); 
    } 
} 

Ecco il mio Contesto

public class SchoolContext : DbContext 
{ 
    public DbSet<Course> Courses { get; set; } 
    public DbSet<Person> People { get; set; } 

    public SchoolContext() 
     : base("MyDb") 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Course>(). 
      HasMany(c => c.Students). 
      WithMany(p => p.CoursesAttending). 
      Map(
       m => 
       { 
        m.MapLeftKey("CourseId"); 
        m.MapRightKey("PersonId"); 
        m.ToTable("PersonCourses"); 
       }); 

    } 
} 

Quando inserisco registri è giusto

static void Main(string[] args) 
{ 
    using (SchoolContext db = new SchoolContext()) 
    { 
     Course math = new Course(); 
     Course history = new Course(); 
     Course biology = new Course(); 
     math.Title = "Math"; 
     history.Title = "History"; 
     biology.Title = "Biology"; 

     db.Courses.Add(math); 
     db.Courses.Add(history); 
     db.Courses.Add(biology); 

     Person john = new Person(); 
     john.FirstName = "John"; 
     john.LastName = "Paul"; 
     john.CoursesAttending.Add(history); 
     john.CoursesAttending.Add(biology); 

     db.People.Add(john); 
     db.SaveChanges(); 
    } 
} 

Ma quando provo selezionare Registro per i contenuti spettacolo, non è un lavoro, ma basta stampare nulla

static void Main(string[] args) 
{ 
    using (SchoolContext db = new SchoolContext()) 
    { 
     Pearson p = db.Peasons.First(); 
     Console.WriteLine(p.CoursesAttending.First().Title); 
    } 
} 

ho avuto il check-in database, esistono registri, qual è il problema?

Per favore, insegnami come selezionare in molti a molti il ​​rapporto con il codice.

+0

Se si utilizza '.Add()' nelle proprietà di navigazione in una relazione molti-a-molti, EF aggiorna automaticamente una tabella comune corrispondente? – Celdor

+0

@Celdor EF aggiorna la tabella di join corrispondente del corso. – IFink

risposta

33

Prima di tutto, si consiglia di abilitare lazy loading, rendendo le collezioni virtuale:

public virtual ICollection<Course> CoursesAttending { get; set; } 
public virtual ICollection<Person> Students { get; set; } 

Questo permette EF per creare classi derivate (proxy) da Course e Person che sostituiscono le collezioni con logica per caricare i loro dati dall'archivio dati.

Quando lo fate vedrete che

Console.WriteLine(p.CoursesAttending.First().Title); 

eseguirà una query separata per popolare CoursesAttending.

In alternativa, o in aggiunta, si può decidere di evitare round trip al database desiderosi di carico in questo modo:

Person p = db.Persons.Include(p => p.CoursesAttending).First(); 

che carica il Persone il CoursesAttending in un solo colpo.

+0

Grande! è lavoro !! Quindi ... perché Include sta usando per selezionare velocemente? Non capisco come usare Include – Lai32290

+1

Come dice la parola, 'Include' include proprietà nella query. Di solito è più efficiente avere una query SQL (con join) piuttosto che ottenere oggetti e interrogare gli oggetti associati in seguito in query separate. –

-1

Rimuovere il costruttore della classe e il metodo OnModelCreating. EF gestisce la relazione da molti a molti. Non devi fare nulla in più.

+6

L'utilizzo delle annotazioni di dati può fornire per impostazione predefinita una convenzione di denominazione funky e fornendo il codice api fluente, questa denominazione indesiderata può essere evitata. –

+0

Questa risposta è IMO OT e non utile a tutti. – Celdor