2008-11-22 4 views
43

Grundfrage: Wie erstelle ich eine bidirektionale 1: n-Karte in Fluent NHibernate?Fluent NHibernate: Wie man One-to-Many bidirektionale Mapping erstellen?

Details:

Ich habe ein übergeordnetes Objekt mit vielen Kindern. In meinem Fall ist es für das Kind bedeutungslos, kein Elternteil zu haben, also möchte ich in der Datenbank, dass der Fremdschlüssel zum Elternteil NOT NULL constraint hat. Ich erstelle automatisch meine Datenbank aus dem Fluent NHibernate Mapping.

ich einen Elternteil mit vielen Kind-Objekten wie folgt:

public class Summary 
{ 
    public int id {get; protected set;} 

    public IList<Detail> Details {get; protected set;} 
} 

public class Detail 
{ 
    public int id {get; protected set;} 

    public string ItemName {get; set;} 

    /* public Summary Owner {get; protected set;} */ //I think this might be needed for bidirectional mapping? 
} 

Hier ist die Abbildung I mit gestartet:

public class SummaryMap : ClassMap<Summary> 
{ 
    public SummaryMap() 
    { 
     Id(x => x.ID); 

     HasMany<Detail>(x => x.Details); 
    } 
} 

public class DetailMap : ClassMap<Detail> 
{ 
    public DetailMap() 
    { 
     Id(x => x.ID); 

     Map(x => x.ItemName).CanNotBeNull(); 
    } 
} 

in der Detailtabelle sollte die Summary_id nicht Null sein, weil In meinem Fall ist es bedeutungslos, ein Detailobjekt nicht an das Zusammenfassungsobjekt anzuhängen. Wenn Sie jedoch nur die Map HasMany() verwenden, bleibt der Fremdschlüssel für die Zusammenfassung_ID leerbar.

Ich fand in der NHibernate docs (http://www.hibernate.org/hib_docs/nhibernate/html/collections.html), dass "Wenn das übergeordnete Element erforderlich ist, verwenden Sie eine bidirektionale Eins-zu-viele-Verknüpfung".

Also wie erstelle ich die bidirektionale Eins-zu-viele-Karte in Fluent NHibernate?

Antwort

54

Um eine bidirektionale Verknüpfung mit einer Nicht-Null-Fremdschlüsselspalte in der Detailtabelle zu erhalten, können Sie die vorgeschlagene Owner-Eigenschaft, ein References (...) .CanNotBeNull() - Mapping in der Klasse DetailsMap hinzufügen und die Zusammenfassung erstellen Ende invers.

Um zwei unterschiedliche Fremdschlüsselspalten für die beiden Zuordnungsrichtungen zu vermeiden, können Sie entweder die Spaltennamen manuell angeben oder die Eigenschaften so benennen, dass für beide Richtungen der gleiche Spaltenname angegeben wird. In diesem Fall empfehle ich, die Eigenschaft Details.Owner in Details.Summary umzubenennen.

Ich habe die Zusammenfassung ID von Inkrement generiert, um Probleme beim Einfügen in die Tabelle seit Zusammenfassung currenty hat keine Spalten neben ID.

Domain:

public class Detail 
{ 
    public int id { get; protected set; } 
    public string ItemName { get; set; } 

    // Renamed to use same column name as specified in the mapping of Summary.Details 
    public Summary Summary {get; set;} 
} 

public class Summary 
{ 
    public Summary() 
    { 
     Details = new List<Detail>(); 
    } 

    public int id { get; protected set; } 
    public IList<Detail> Details { get; protected set; } 
} 

Mapping:

public class DetailMap : ClassMap<Detail> 
{ 
    public DetailMap() 
    { 
     Id(x => x.id) 
      .GeneratedBy.Native(); 

     Map(x => x.ItemName) 
      .CanNotBeNull(); 

     References<Summary>(x => x.Summary) 
      // If you don't want to rename the property in Summary, 
      // you can do this instead: 
      // .TheColumnNameIs("Summary_id") 
      .CanNotBeNull(); 
    } 
} 

public class SummaryMap : ClassMap<Summary> 
{ 
    public SummaryMap() 
    { 
     Id(x => x.id) 
      .GeneratedBy.Increment(); 

     HasMany<Detail>(x => x.Details) 
      .IsInverse() 
      .AsBag(); // Use bag instead of list to avoid index updating issues 
    } 
} 
+8

Gibt es wirklich keine Möglichkeit, die Fremdschlüsselspalte zu machen "nicht nullable" ohne auf das Kind einen Verweis auf das übergeordnete Hinzufügen ? –

+2

+1 Ich wünschte, ich könnte wieder abstimmen. –

Verwandte Themen