我不是一个高级的NHibernate用户,所以这可能有点重要,我还没发现它......但是到底是什么。
考虑课程:
public class House
{
public int Id { get; set; }
public ISet<Room> Rooms
{
get;
set;
}
}
当指定NHibernate Set元素时,编写它是不够的:
<set name="Rooms" />
相反,我必须写至少:
<set name="Rooms">
<key column="RoomId"/>
<one-to-many class="Room"/>
</set>
这似乎违反了DRY原则。 如果它是一个Set,则默认值应该是它是一对多的关系。该类应该从集合的泛型类型推断出来,作为键列,应该使用集合元素类的主键。
在我看来,这似乎是一个合理的默认值。为什么然后,NHiberbate并不聪明,并要求我输入这3条额外的线?
答案 0 :(得分:1)
因为,我认为,当NH根据映射创建代理时,还需要更长的时间来完成程序集,并通过反射来确定它需要做什么。这将增加NH工厂的启动时间。
别忘了,它是关系映射器的一个对象。您至少需要一个额外的节点(密钥)来告诉它需要使用的数据库密钥是什么。这使您可以在映射到数据库时保持灵活,而不是硬连线到默认值。
它会破坏DRY吗?有可能。在这种情况下我关心吗?不,不是真的。
答案 1 :(得分:0)
您可以查看Fluent NHibnernate。他们的DSL受DRY的启发。
修改强> 对不起应该仔细阅读...
关于你的例子,Fluent NHibernate允许你将映射表达为:
HasMany(x => x.Rooms);
但是,HasMany(或One-To-Many)关系映射到IList。我不确定这是否可以进一步定制(让Fluent默认映射到ISet)。但无论哪种方式,它都不如标准的映射声明重复。
以下是一些声明映射的示例:Fluent NHibernate Wiki。
答案 2 :(得分:0)
如果您不使用通用集合怎么办? 如果我没弄错的话,NHibernate只支持版本1.2中的泛型;所以在以前的版本中,绝对不可能进行类型推断。
如果使用旧数据库,其主要ID未用作相关表中的外键,该怎么办?