处理NHibernate中的大类继承层次结构

时间:2011-08-02 14:38:11

标签: nhibernate domain-driven-design nhibernate-mapping

我的模型看起来像这样:

  • InsurancePolicy
    • VehicleInsurancePolicy
      • AbcInsurancePolicy
      • DefInsurancePolicy
    • HomeInsurancePolicy
      • GhiInsurancePolicy
      • PqrInsurancePolicy
    • SomeOtherInsurancePolicy
      • ...... etc

其中InsurancePolicy是一个抽象类,它是保险单的所有具体实现的基类。 AbcInsurancePolicy,DefInsurancePolicy等是与某些保险产品相对应的实施方式。有时我会为具有公共字段子集的策略子组定义其他抽象类(如VehicleInsurancePolicy)。

我使用“每个子类的表,使用鉴别器”策略映射这些类。 InsurancePolicy表包含大约60个字段,每个连接表添加10到30个字段。我使用这种策略是因为:

  • 我有很多具有很多字段的子类。每个类的表层次结构策略将结束具有大量空列的单个表。
  • 我希望能够通过添加其他子类来扩展应用程序,而无需更改InsurancePolicy表的架构。

InsurancePolicy通常用作支付,文档等其他实体的多对一关系。

NHibernate在查询InsurancePolicy时会生成大量的左外连接,因为它不知道类型。这是非常低效的,因为我有很多表要加入。当懒惰加载包含InsurancePolicy的多对一属性时,问题变得更加严重,因为它在我的模型中使用了很多。具体实现很少使用,仅在编辑/详细信息场景中使用,其中指定实际类型并且仅连接所需的表。

然后我使用了discrimator + join的组合。因此InsurancePolicy表包含有关类型的信息。不幸的是,“连接”映射不支持延迟加载。我尝试设置fetch =“select”,但是在查询多个保险单时会产生N + 1选择。

// select from 1 table, "join" class must be lazy-loaded on access
Session.Get<InsurancePolicy>(5) 

// select includes a join, since we explicitly specified a concrete type
Session.Get<SomeConcreteInsurancePolicy>(5)

所以我的问题是:

  1. 有没有办法扩展NHibernate以使其像上面一样工作?
  2. 是否有另一种映射这些大型/复杂类层次结构的方法?

1 个答案:

答案 0 :(得分:2)

基于此:

  

具体实现很少使用,仅在编辑/详细信息场景中使用

我建议你将InsurancePolicy分解为两个:

  • InsurancePolicy,仅包含当前基类的属性
  • PolicyDetails,层次结构的抽象基类。

这两个班级之间存在一对一的关系。

这样做的好处是您不必更改任何其他内容(除了政策编辑视图中的微小更改,指向新关系)