Моя модель выглядит следующим образом:
- InsurancePolicy
- VehicleInsurancePolicy
- AbcInsurancePolicy
- DefInsurancePolicy
- Домашняя страховкаПолиция
- GhiInsurancePolicy
- PqrInsurancePolicy
- SomeOtherInsurancePolicy
где InsurancePolicy - это абстрактный класс, который является базовым классом для всех конкретных реализаций страховых полисов.AbcInsurancePolicy, DefInsurancePolicy и т. Д. Являются реализациями, которые соответствуют определенным страховым продуктам.Иногда я определяю другие абстрактные классы для подгрупп политик с подмножеством общих полей (например, VehicleInsurancePolicy).
Я сопоставил эти классы, используя стратегию «Таблица на подкласс, используя дискриминатор».Таблица InsurancePolicy содержит около 60 полей, и каждая объединенная таблица добавляет от 10 до 30 полей.Я использовал эту стратегию, потому что:
- У меня много подклассов с большим количеством полей.Стратегия таблица-на-класс-иерархия закончилась бы наличием одной таблицы с большим количеством пустых столбцов.
- Я хочу иметь возможность расширять приложение, добавляя другие подклассы, не изменяя схему таблицы InsurancePolicy.
InsurancePolicy часто используется как отношение «многие-к-одному» в других объектах, таких как «Оплата», «Документ» и т. Д.
NHibernate генерирует много левых внешних соединений при запросах к InsurancePolicy.потому что он не знает тип.Это очень неэффективно, так как мне нужно присоединиться ко многим столам.Проблема становится еще хуже, когда лениво загружаются свойства многие-к-одному, содержащие InsurancePolicy, потому что он довольно часто используется в моей модели.Конкретные реализации используются редко, только в сценариях редактирования / подробностей, где указывается фактический тип и объединяются только необходимые таблицы.
Тогда я использовал комбинацию дискриминатор + соединение.Таким образом, таблица InsurancePolicy содержит информацию о типе.К сожалению, отображение "join" не поддерживает отложенную загрузку.Я попытался установить 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, чтобы он работал, как описано выше?
- Есть ли другой способ сопоставления этихбольшие / сложные иерархии классов?