NHibernate 集合映射不是 DRY 吗?

Posted

技术标签:

【中文标题】NHibernate 集合映射不是 DRY 吗?【英文标题】:NHibernate set mapping is not DRY? 【发布时间】:2009-03-12 11:59:54 【问题描述】:

我不是高级 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 行呢?

【问题讨论】:

【参考方案1】:

因为,我认为,当 NH 基于映射创建代理时,还需要更长的时间来检查您的程序集,并通过反射来确定它需要做什么。这会增加 NH 工厂的启动时间。

别忘了,它是关系映射器的对象。您至少需要一个额外的节点(密钥)来告诉它需要使用的数据库密钥是什么。这允许您在映射到 DB 时尽可能灵活,而不是硬连线到默认值。

它会破坏 DRY 吗?可能。我在乎这种情况吗?不,不是。

【讨论】:

【参考方案2】:

如果你不使用泛型集合怎么办? 如果我没记错的话,NHibernate 只支持从 1.2 版开始的泛型;所以在以前的版本中,类型推断是绝对不可能的。

如果您使用旧数据库,其中主 ID 不用作相关表中的外键,该怎么办?

【讨论】:

那么我不会使用默认值。然而,将这些值作为默认值将是有意义的恕我直言。即使在 .NET 1.1 时代这是有道理的,但它不再有意义了。那么它是剩菜吗?【参考方案3】:

你可以看看Fluent NHibnernate。他们的 DSL 受到 DRY 的启发。

编辑: 抱歉应该更仔细阅读...

关于您的示例,Fluent NHibernate 将允许您将映射表示为:

HasMany(x => x.Rooms);

但是,HasMany(或一对多)关系映射到 IList。我不确定这是否可以进一步定制(让 Fluent 默认映射到 ISet)。但无论哪种方式,它的重复性都比标准映射声明要少。

以下是一些声明映射的示例:Fluent NHibernate Wiki。

【讨论】:

我知道 FluentNHibernate。然而,这对我来说不是一个选择,它仍然不能回答这个问题。

以上是关于NHibernate 集合映射不是 DRY 吗?的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate3剖析:Mapping篇之集合映射基础:List映射

Fluent NHibernate:在映射中急切加载多个集合

没有外键的NHibernate映射集合

Fluent Nhibernate将集合映射到通用实体

为啥这两个 NHibernate 查询会产生不同的结果?

NHibernate的主键是1-1映射吗?