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

发布于 2024-11-27 15:40:53 字数 1310 浏览 0 评论 0原文

我的模型如下所示:

  • InsurancePolicy
    • 车辆保险单
      • Abc保险保单
      • DefInsurancePolicy
    • 首页保险单
      • Ghi保险保单
      • Pqr保险单
    • 一些其他保险单
      • ...等

,其中 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. 是否有另一种方法来映射这些大型/复杂的类层次结构?

My model looks like this:

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

where InsurancePolicy is an abstract class which is the base class for all concrete implementations of insurance policies. AbcInsurancePolicy , DefInsurancePolicy , etc are implementations which correspond to a certain insurance products. Sometimes I define other abstract classes for subgroups of policies with a subset of common fields (like VehicleInsurancePolicy).

I mapped this classes using a "Table per subclass, using a discriminator" strategy. The InsurancePolicy table contains about 60 fields, and each joined table adds from 10 to 30 fields. I used this strategy because:

  • I have a lot of subclasses with a lot of fields. A table-per-class-hierarchy strategy would end having a single table with a lot of null columns.
  • I want to be able to extend the application by adding other subclasses without changing the schema of InsurancePolicy table.

The InsurancePolicy is used often as a many-to-one relationship in other entities like Payment, Document etc.

NHibernate generates a lot of left-outer-joins when querying for InsurancePolicy because it doesn't know the type. This is very inefficient as I have a lot of tables to join. The problem becomes even worse when lazy-loading many-to-one properties containing an InsurancePolicy because it is used quite a lot in my model. The concrete implementations are used rarely, only in edit/details scenarios where it is specified the actual type and only the needed tables are joined.

Then I used a combination of discrimator + join. Thus the InsurancePolicy table contains the information about the type. Unfortunately a "join" mapping doesn't support lazy-loading. I tried setting fetch="select", however these generates N+1 selects when querying for multiple insurance policies.

// 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)

So my questions are:

  1. Is there a way to extend NHibernate to make it work like above?
  2. Is there another way of mapping these large / complex class hierarchies?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

_畞蕅 2024-12-04 15:40:53

基于此:

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

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

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

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

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

Based on this:

The concrete implementations are used rarely, only in edit/details scenarios

I recommend that you break up InsurancePolicy in two:

  • InsurancePolicy, containing only the properties from the current base class
  • PolicyDetails, an abstract base class for the hierarchy.

There's a one-to-one relationship between those two classes.

The beauty of this is that you don't have to change anything else (except a minor change in the policy edit views, to point them to the new relationship)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文