具有自然键的流畅 NHibernate 引用实体

Posted

技术标签:

【中文标题】具有自然键的流畅 NHibernate 引用实体【英文标题】:Fluent NHibernate referencing entity with natural key 【发布时间】:2011-07-11 00:43:25 【问题描述】:

我正在使用 Fluent NHibernate 自动映射功能。我已经设法使用约定使数据库映射非常接近,但有一些事情我需要 IAutoMappingOverride。

在旧系统中,我有一个实体类“Campus”,它有一个 NATURAL 键“代码”。该键的 Oracle 数据库类型是 VARCHAR2(3 BYTE)。我为此使用了覆盖,因为我的约定否则会假定自动生成的代理键。我有其他引用 Campus 实体(带有其自然键)的实体类(例如 Building),如下所示

<class name="Campus" table="CAMPUS" ... >
<id name="Id" type="String">
  <column name="camp_code" sql-type="VARCHAR2(3 BYTE)" />
  <generator class="assigned" />
</id>
<set name="Buildings" ...>
  <key foreign-key="buil_camp_fk">
    <column name="camp_code" />
  </key>
  <one-to-many class="Building" />
</set>
...
</class>

<class name="Building" table="BUILDING" ... >
...
<many-to-one class="Campus" name="Campus">
<column name="camp_code" not-null="true" />
</many-to-one>
...
</class>

使用以下覆盖,我生成的 HBM 映射似乎是正确的:

Public Class CampusMappingOverride
Implements IAutoMappingOverride(Of Campus)

Public Sub Override(ByVal mapping As AutoMapping(Of Campus)) Implements IAutoMappingOverride(Of Campus).Override
  mapping.Id(Function(campus) campus.Id, "camp_code").CustomSqlType("VARCHAR2(3 BYTE)")
End Sub

End Class

Public Class BuildingMappingOverride
Implements IAutoMappingOverride(Of Building)

Public Sub Override(ByVal mapping As AutoMapping(Of Building)) Implements IAutoMappingOverride(Of Building).Override
  mapping.References(Of Campus)(Function(building) building.Campus, "camp_code")
End Sub

End Class

但是,模式导出(Oracle 数据库)不正确。

create table BUILDING (
   ...
   camp_code NVARCHAR2(255) not null,
   ...
)
create table CAMPUS (
   camp_code VARCHAR2(3 BYTE) not null,
   ...
   primary key (camp_code)
)

如您所见,building.camp_code 是 NVARCHAR2(255),这似乎是 Oracle 中 String 的默认值,但它应该是 VARCHAR2(3 BYTE)。

我看到有一个 mapping.NaturalId 函数,但我不确定它是否正常工作,因为如果我用它代替 Id,我会得到一个映射异常。

对于如何处理这种情况的任何帮助,我将不胜感激。

亲切的问候, 瑞恩。

【问题讨论】:

【参考方案1】:

我同意你的观点,FNH 应该将关联另一端的列类型识别为 VARCHAR,但显然它没有。在the FNH mailing list 询问可能是值得的

但为了解决您当前的问题,我认为在您对 Building 的映射覆盖中,您可以准确指定要使用的列类型(使用 Column() 函数),以便您可以自行纠正该行为。

【讨论】:

感谢您的回复。我将查看 FNH 邮件列表。干杯。我认为我不能使用 ManyToOneBuilder(Of TOther) 的 Column() 函数来做我需要的事情,因为这只是设置了列名(我已经正确设置了)。 ManyToOneBuilder(Of TOther) 没有 CustomSqlType 函数。我注意到有人提出了类似的question。

以上是关于具有自然键的流畅 NHibernate 引用实体的主要内容,如果未能解决你的问题,请参考以下文章

IList<int> 的流畅 NHibernate 映射?

NHibernate 中的自引用实体给对象引用一个未保存的瞬态实例异常

流畅的 nHibernate 数据库连接

没有外键的NHibernate映射集合

将引用作为属性的 Nhibernate 映射值对象

使用 nHibernate 选择具有许多子集合的实体的性能不佳