Fluent NHibernate: How to create one-to-many bidirectional mapping?

The main question . How to create a one-to-many bidirectional map in Fluent NHibernate?

Details:

I have a parent with a lot of children. In my case, it makes no sense for a child not to have a parent, so in the database I would like the foreign key for the parent to have a NOT NULL constraint. I automatically generate my database from the Fluent NHibernate mapping.

I have a parent with many children:

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

Here is the mapping I started with:

 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 the Detail table, Summary_id should be Not Null, because in my case it makes no sense to have a Detail object that is not tied to the resulting object. However, only the use of the HasMany () card leaves the understated Summary_id key invalid.

I found in NHibernate docs ( http://www.hibernate.org/hib_docs/nhibernate/html/collections.html ): "If a parent element is required, use a one-to-many bidirectional relationship."

So, how do I create a one-to-many bidirectional map in Fluent NHibernate?

+43
nhibernate fluent-nhibernate nhibernate-mapping
Nov 22 '08 at 0:42
source share
1 answer

To get a bi-directional relationship with a non-zero column of a foreign key in the Details table, you can add the proposed property Owner, matching Links (...). CanNotBeNull () in the "DetailsMap" class and reverse the summary information.

To avoid two different foreign key columns for two directions of association, you can specify column names manually or name the properties so that they indicate the same column name for both directions. In this case, you are proposing to rename the Details.Owner property to Details.Summary.

I made the Summary identifier generated by the increment to avoid problems when pasting into the table, since Summary currenty has no columns except 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 } } 
+54
Nov 22 '08 at 9:36
source share
— -



All Articles