stream利的NHibernate:如何创build一对多的双向映射?
基本问题 :如何在Fluent NHibernate中创build一个双向一对多的地图?
细节:
我有许多孩子的父母对象。 在我的情况下,孩子没有父母没有意义,所以在数据库中,我希望父母的外键具有NOT NULL约束。 我从Fluent NHibernate映射自动生成我的数据库。
我有一个有很多子对象的父类,如下所示:
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? }
这里是我开始的映射:
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(); } }
在Detail表中,Summary_id应该是Not Null,因为在我的情况下,将Detail对象不附加到摘要对象是毫无意义的。 但是,只使用HasMany()映射会将Summary_id外键保留为空。
我在NHibernate文档( http://www.hibernate.org/hib_docs/nhibernate/html/collections.html )中发现:“如果父代是必需的,则使用双向一对多关联”。
那么如何在Fluent NHibernate中创build双向的一对多映射?
要在Details表中获得与非空外键列的双向关联,您可以在DetailsMap类中添加build议的Owner属性,References(…)。CanNotBeNull()映射,并使Summary反转。
为了避免在两个关联方向上有两个不同的外键列,您可以手动指定列名,也可以为两个方向指定相同的列名。 在这种情况下,我build议将Details.Owner属性重命名为Details.Summary。
由于Summary currenty除了id之外没有列,所以我通过增加生成了Summary id以避免插入到表中时出现问题。
域:
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; } }
制图:
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 } }