【问题标题】:Dealing with large class inheritance hierarchies in NHibernate在 NHibernate 中处理大型类继承层次结构
【发布时间】:2011-08-02 14:38:10
【问题描述】:

我的模型如下所示:

  • 保险政策
    • 车辆保险政策
      • AbcInsurancePolicy
      • DefInsurancePolicy
    • 家庭保险政策
      • GhiInsurancePolicy
      • PqrInsurancePolicy
    • SomeOtherInsurancePolicy
      • ...等

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

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

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

InsurancePolicy 在其他实体(如付款、文档等)中通常用作多对一关系。

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

然后我使用了鉴别器+连接的组合。因此 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. 还有其他方法可以映射这些大型/复杂的类层次结构吗?

【问题讨论】:

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


    【解决方案1】:

    基于此:

    很少使用具体的实现,只在编辑/细节场景中使用

    我建议您将 InsurancePolicy 分成两部分:

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

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

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

    【讨论】:

    • 一对一映射似乎是个好主意。但是,我想使用子类映射将类层次结构保持在 InsurancePolicy 级别,其中每个不同的子类将定义不同类型的详细信息对象(映射为一对一)。尽管我不经常使用“详细信息属性”,但有一些业务逻辑会检查 InsurancePolicy 的实际类型并根据它执行不同的操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    相关资源
    最近更新 更多