2013-07-13 16 views
6

La mia domanda è: esiste una mappatura Fluent NHibernate per oggetti padre e figlio che non richiede che l'oggetto Child abbia una proprietà dell'oggetto Parent? Non ho capito come mappare il riferimento al genitore. Quando chiamo Create with the mappings as-is, ottengo un'eccezione perché l'oggetto Child non ha la chiave esterna richiesta (richiesta nell'archivio dati) per il Parent.Chiave esterna della mappa in Fluent NHibernate senza proprietà dell'oggetto

Ho due classi POCO:

public class Parent 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IList<Child> Childs { get; set; } 
} 

public class Child 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual int ParentId { get; set; } 
} 

e alcune mappature:

public class ParentMap : ClassMap<Parent> 
{ 
    public ParentMap() 
    { 
     this.Table("Parents"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.HasMany(x => x.Childs).KeyColumn("ChildId").Cascade.AllDeleteOrphan(); 
    } 
} 

public class ChildMap : ClassMap<Child> 
{ 
    public ChildMap() 
    { 
     this.Table("Childs"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     // Needs some sort of mapping back to the Parent for "Child.ParentId" 
    } 
} 

e creare metodo:

public Parent Create(Parent t) 
{ 
    using (this.session.BeginTransaction()) 
    { 
     this.session.Save(t); 
     this.session.Transaction.Commit(); 
    } 
    return t; 
} 

voglio essere in grado di creare un oggetto principale che ha una lista di oggetti Child, ma non ha gli oggetti Child che hanno riferimenti al loro Parent (tranne l'ID Genitore). Voglio farlo per evitare il riferimento circolare da padre a un elenco di Childs all'oggetto Parent, poiché ciò sta causando problemi con la serializzazione JSON.

+0

È l'associazione della proprietà padre (in "Bambino") a un campo privato un'opzione? –

+0

Questo è quello che sto facendo, anche se sto cercando di evitarlo dal momento che non posso quindi eseguire query sulla proprietà 'ParentId'. Sembra che dovrei essere in grado di mappare una proprietà con un vincolo di chiave esterna a una colonna senza richiedere un oggetto ... –

+0

Nel caso della domanda originale, la risposta di Felipe è corretta. Non serializzare direttamente le entità, trasformale prima in un DTO o in un ViewModel, ottenendo prima la struttura esatta che desideri. –

risposta

3

È possibile mappare queste entità senza problemi, provate questo:

public class ParentMap : ClassMap<Parent> 
{ 
    public ParentMap() 
    { 
     this.Table("Parents"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.HasMany(x => x.Childs).KeyColumn("ChildId").Cascade.AllDeleteOrphan(); 
    } 
} 

public class ChildMap : ClassMap<Child> 
{ 
    public ChildMap() 
    { 
     this.Table("Childs"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.Map(x => x.ParentId); 
     // if you have a reference of Parent object, you could map as a reference, for sample: 
     this.References(x => x.Parent).Column("ParentId"); 
    } 
} 

Quando si arriva entità da ISession, non serializzare a qualche formato, perché questi possono essere deleghe di NHibernate, invece entità oggetti. Prova a creare DTO (Data Transfer Object) classes e converti queste entità in un oggetto DTO e serializzalo. Eviterete riferimenti circolari. Per esempio:

public class ParentDTO 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int ParentId { get; set; } 

    /* here you just have the primitive types or other DTOs, 
     do not reference any Entity type*/ 
} 

E quando hai bisogno di leggere i valori di condividere il valore serializzato:

var dto = ISession.Query<Parent>() 
        .Select(x => 
         new ParentDTO() { 
          Id = x.Id, 
          Name = x.Name, 
          ParentId = x.ParentId) 
        .ToList(); 

ottenere questo risultato dalla Data Access Layer e cercare di serializzare, per il campione:

var result = Serialize(dto); 
+1

Un elemento fondamentale per me che la risposta non è indirizzata è la proprietà 'ParentId' deve avere un vincolo di chiave esterna sulla proprietà' Id' dell'oggetto 'Parent'. Devi semplicemente "mappare", quindi non ha alcun vincolo su di esso. –

+0

Sono d'accordo con te @PatrickQuirk, ma nel modello che l'OP fornito non ha un riferimento, solo un 'Id'. –

Problemi correlati