2013-07-13 3 views
6

Meine Frage ist, gibt es eine mögliche Fluent NHibernate Mapping für Parent-und Child-Objekte, die nicht erfordert das Child-Objekt, eine Parent-Objekteigenschaft zu haben? Ich habe nicht herausgefunden, wie man die Referenz zurück auf das Elternobjekt abbildet. Wenn ich Create mit den Zuordnungen so wie sie ist aufrufen, erhalte ich eine Ausnahme, weil das Child-Objekt nicht den erforderlichen Fremdschlüssel (im Datenspeicher erforderlich) zurück zum Parent hat.Map Fremdschlüssel in Fluent NHibernate ohne Objekteigenschaft

Ich habe zwei POCO Klassen:

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

Und einige Zuordnungen:

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

Und Create-Methode:

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

Ich möchte ein übergeordnetes Objekt erstellen können, dass hat eine Liste von Child-Objekten, aber die Child-Objekte haben keine Referenzen zurück zu ihrem Parent (außer der Eltern-ID). Ich möchte dies tun, um den Zirkelverweis von Parent auf eine Liste von Childs zurück zum Parent-Objekt zu vermeiden, da dies Probleme mit der JSON-Serialisierung verursacht.

+0

Ist die Elterneigenschaft (in 'Child') zu einem privaten Feld eine Option? –

+0

Das ist, was ich tue, obwohl ich versuche, es zu vermeiden, da ich dann Abfragen auf der Eigenschaft 'ParentId' nicht ausführen kann. Es scheint, als ob ich in der Lage wäre, eine Eigenschaft mit einer Fremdschlüsseleinschränkung einer Spalte zuzuordnen, ohne ein Objekt zu benötigen ... –

+0

Im Fall der ursprünglichen Frage ist Felipes Antwort richtig. Serialisieren Sie die Entitäten nicht direkt, wandeln Sie sie erst in ein DTO oder ViewModel um und erhalten Sie zuerst die gewünschte Struktur. –

Antwort

3

Sie können diese Einheiten problemlos abzubilden, versuchen Sie dies:

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

Wenn Sie Objekte aus ISession bekommen, serialisieren es nicht zu einem gewissen Format, da diese Proxies von nhibernate stattdessen Entitäten Objekte sein können. Versuchen Sie, DTO (Data Transfer Object) classes zu erstellen, und konvertieren Sie diese Entitäten in ein DTO-Objekt, und serialisieren Sie sie. Sie vermeiden zirkuläre Referenzen. Für Beispiel:

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*/ 
} 

Und wenn müssen Sie die Werte lesen, die serialisierte Wert zu teilen:

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

dieses Ergebnis aus dem Data Access Layer und versuchen, für Probe zu serialisiert,:

var result = Serialize(dto); 
+1

Ein kritisches Stück für mich, das Ihre Antwort nicht anspricht, ist, dass die ParentId-Eigenschaft eine Fremdschlüsseleinschränkung für die Id-Eigenschaft des Parent-Objekts haben muss. Du hast es nur "gemappt", also hat es keinerlei Einschränkungen. –

+0

Ich stimme mit dir @PatrickQuirk, aber in dem Modell, dass OP zur Verfügung gestellt hat keine Referenz, nur eine "Id". –

Verwandte Themen