在 NHibernate 中处理大型类继承层次结构
我的模型如下所示:
- 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)
所以我的问题是:
- 有没有办法扩展 NHibernate 使其像上面那样工作?
- 是否有另一种方法来映射这些大型/复杂的类层次结构?
My model looks like this:
- InsurancePolicy
- VehicleInsurancePolicy
- AbcInsurancePolicy
- DefInsurancePolicy
- HomeInsurancePolicy
- GhiInsurancePolicy
- PqrInsurancePolicy
- SomeOtherInsurancePolicy
- ... etc
- VehicleInsurancePolicy
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:
- Is there a way to extend NHibernate to make it work like above?
- Is there another way of mapping these large / complex class hierarchies?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
基于此:
我建议您将 InsurancePolicy 分成两部分:
这两个类之间存在一对一的关系。
这样做的好处是您不必更改任何其他内容(除了策略编辑视图中的微小更改,以将它们指向新关系)
Based on this:
I recommend that you break up InsurancePolicy in two:
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)