8

Ho creato un tipo di entità che ha più proprietà di raccolta che fanno riferimento a elementi dello stesso tipo. In altre parole, riflette una singola tabella di database in cui le righe sono raggruppate in modo arbitrario, in modo tale che una riga possa apparire in più gruppi.Codice quadro entità Primo: come mappare più relazioni autoreferenziali molti-a-molti

Nel seguente esempio semplificato, la classe Person ha Brothers e Sisters raccolta proprietà che fanno riferimento anche Person entità:

public class Person 
{ 
    public Person() 
    { 
     Brothers = new Collection<Person>(); 
     Sisters = new Collection<Person>(); 
    } 

    [Key] 
    public string Name { get; set; } 

    public int Age { get; set; } 

    public virtual ICollection<Person> Brothers { get; set; } 

    public virtual ICollection<Person> Sisters { get; set; } 
} 

Entity Framework sembra pensare che questo è un modello valido, ma lo interpreta per creare un Single PersonPersons join table, che non riflette la separazione tra le relazioni fratello e sorella.

Suppongo che la soluzione sia utilizzare l'API fluente per mappare esplicitamente tabelle di join separate per le due relazioni ma, nonostante la vasta sperimentazione, non sono riuscito a farlo funzionare.

Qualche suggerimento, per favore?

Grazie, Tim

+1

Hai provato, HasMany (p => p.Brothers) .WithMany (b => b.Persons) .Map (m => m.Table ("Person_Brothers"); non hanno provato questo tipo di relazione ma che noi facciamo una mappa di molti a molti quando ef non collaborerà – trevorc

risposta

8

aggiungendo questo nel metodo DbContext.OnModelCreating:

UPDATE Aggiunto mappa tabella di denominazione in base al commento di nameEqualsPNamePrubeGoldberg sopra:

modelBuilder.Entity<Person>().HasMany(x => x.Brothers).WithMany() 
    .Map(x => x.ToTable("Person_Brothers")); 
modelBuilder.Entity<Person>().HasMany(x => x.Sisters).WithMany() 
    .Map(x => x.ToTable("Person_Sisters")); 

ho ottenuto questo unit test per passare

[TestMethod] 
public void TestPersons() 
{ 
    var brother = new Person() { Name = "Brother 1", Age = 10 }; 
    var sister = new Person() { Name = "Sister 1", Age = 12 }; 
    var sibling = new Person() { Name = "Sibling 1", Age = 18 }; 
    sibling.Brothers.Add(brother); 
    sibling.Sisters.Add(sister); 

    using (var db = new MyDatabase()) 
    { 
     db.Persons.Add(brother); 
     db.Persons.Add(sister); 
     db.Persons.Add(sibling); 

     db.SaveChanges(); 
    } 

    using (var db = new MyDatabase()) 
    { 
     var person = db.Persons 
      .Include(x => x.Sisters) 
      .Include(x => x.Brothers) 
      .FirstOrDefault(x => x.Name.Equals(sibling.Name)); 

     Assert.IsNotNull(person, "No person"); 
     Assert.IsTrue(person.Brothers.Count == 1, "No brothers!"); 
     Assert.IsTrue(person.Sisters.Count == 1, "No sisters"); 
    } 
} 

Ciò crea anche le tabelle di collegamento di cui si sta parlando.

+1

Questa è un'ottima soluzione, grazie –

+0

con questo codice, tu dici che 'brother' è un fratello di' sibling', giusto? ma poi devi manualmente includi l'altro lato della relazione (dicendo che 'fratello 'è fratello di' fratello')? – tyron

+0

@tyron: Sì, penso che tu abbia ragione: –

Problemi correlati