Недопустимое свойство подкласса NHiberate
Я пытаюсь решить эту проблему, когда подкласс содержит набор свойств, однако в указанной таблице не существует двух свойств.
Эти два свойства существуют в таблице расширений, в которой FK возвращаются к базовой таблице. Я не уверен, как изменить этот XML для поддержки первого присоединенного подкласса и добавления другого объединения для таблицы расширений.
Я попытался просто добавить еще один присоединенный подкласс для таблицы Extension, однако, поскольку имя класса было таким же, отображение было недопустимым.
<joined-subclass name="SESProgramAssociationAggregate.SESProgramAssociation" table="SESProgramAssociation" lazy="false">
<key>
<column name="BeginDate" />
<column name="EOId" />
<column name="PEOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="UDI" />
</key>
<!-- PK properties -->
<property name="UDI" column="UDI" type="int" not-null="true" insert="false" />
<property name="ProgramTypeId" column="ProgramTypeId" type="int" not-null="true" insert="false" />
<property name="PEOrganizationId" column="PEOrganizationId" type="int" not-null="true" insert="false" />
<property name="BeginDate" column="BeginDate" type="date" not-null="true" insert="false" />
<property name="ProgramName" column="ProgramName" type="string" length="60" not-null="true" insert="false" />
<property name="EOId" column="EOId" type="int" not-null="true" insert="false" />
<!-- Properties -->
<property name="Eligibility" column="Eligibility" type="bool" />
<property name="SESDescriptorId" column="SESDescriptorId" type="int" not-null="true" />
<property name="SEHoursPerWeek" column="SEHoursPerWeek" type="decimal" />
<property name="HoursPerWeek" column="HoursPerWeek" type="decimal" />
<property name="MultiplyD" column="MultiplyD" type="bool" />
<property name="MFragile" column="MFragile" type="bool" />
<property name="LastEvalDate" column="LastEvalDate" type="date" />
<property name="ReviewDate" column="ReviewDate" type="date" />
<property name="BeginDate" column="BeginDate" type="date" />
<property name="EndDate" column="EndDate" type="date" />
<property name="EventCode" column="EventCode" type="int" />
<property name="WrittenConsentDate" column="WrittenConsentDate" type="date" />
</joined-subclass>
Последний сгенерированный запрос завершается неудачно, потому что он пытается сослаться на EventCode и WrittenConsentDate из таблицы SESProgramAssociation, где они не существуют. Они действительно существуют в таблице расширений.
Я не уверен, как изменить этот XML-файл, чтобы указывать эти поля на таблицу расширений, чтобы сгенерированный запрос фактически извлекал их из этой таблицы, а не из неправильной. Любая помощь очень ценится, это мой первый опыт с NHiberate и, разумеется, это не было весело!
После совета от Фредерика я обновился, но получил эту ошибку:
Исключение типа "NHibernate.MappingException" произошло в NHibernate.dll, но не было обработано в коде пользователя
Дополнительная информация: EdFi.Ods.Entities.NHibernate.Mappings.SqlServer.StudentProgramAssociationBase.hbm.xml (79,8): Ошибка проверки XML: элемент 'join-subclass' в пространстве имен 'urn: nhibernate-mapping-2.2' имеет недопустимый дочерний элемент 'join' в пространстве имен 'urn: nhibernate-mapping-2.2'. Список возможных ожидаемых элементов: 'свойство, многие-к-одному, один-к-одному, компонент, динамический компонент, свойства, любые, карта, набор, список, сумка, пакет idbag, массив, массив примитивов, объединенный подкласс, загрузчик, sql-insert, sql-update, sql-delete, resultset, query, sql-query 'в пространстве имен' urn: nhibernate-mapping-2.2 '.
1 ответ
Ваш второй стол не должен отображаться как другой joined-subclass
, поскольку он не соответствует подклассу в модели вашего домена.
Это должно быть сопоставлено либо как отдельный Extension
с расширенным объектом, ссылающимся на него как one-to-one
связанный объект.
Или вы можете использовать join
отображение наличия единой сущности в вашей доменной модели. Но join
отображение не разрешено subclass
, так что вам придется использовать его в своем базовом классе, если вы можете добавить к нему эти свойства. Как настроить отображение пастбина в комментариях:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Entities.NHibernate"
namespace="Entities.NHibernate.SPAssociationAggregate"
default-access="property">
<!-- Class definition -->
<class name="SPAssociationBase" table="SPAssociation" lazy="false">
<!-- Composite primary key -->
<composite-id>
<key-property name="BeginDate" type="date" />
<key-property name="OrganizationId" />
<key-property name="ProgramOrganizationId" />
<key-property name="ProgramName" length="60" />
<key-property name="ProgramTypeId" />
<key-property name="SUSI" />
</composite-id>
<!-- Optimistic locking for aggregate root -->
<version name="LastModifiedDate" type="timestamp" />
<!-- Transient state detection -->
<property name="CreateDate" type="DateTime" />
<!-- Unique Guid-based identifier for aggregate root -->
<property name="Id" />
<!-- Properties -->
<property name="EndDate" type="date" />
<property name="ReasonExitedDescriptorId" />
<property name="ServedOutsideOfRegularSession" />
<!-- Collections -->
<bag name="SPAssociationServices" cascade="all-delete-orphan" inverse="true" lazy="false">
<key>
<column name="BeginDate" />
<column name="OrganizationId" />
<column name="ProgramOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="SUSI" />
</key>
<one-to-many class="SPAssociationServiceForBase" />
</bag>
<!-- Extended properties -->
<join table="SSEPAssociationExtension" optional="true">
<key>
<column name="BeginDate" />
<column name="OrganizationId" />
<column name="ProgramOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="SUSI" />
</key>
<property name="EventCode" />
<property name="WrittenConsentDate" />
</join>
<!-- Derived classes -->
<joined-subclass name="SESProgramAssociationAggregate.SESProgramAssociation" table="SESProgramAssociation" lazy="false">
<key>
<column name="BeginDate" />
<column name="OrganizationId" />
<column name="ProgramOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="SUSI" />
</key>
<!-- Properties -->
<property name="IdeaEligibility" />
<property name="DescriptorId" />
<property name="HoursPerWeek" />
<property name="SHoursPerWeek" />
<property name="MultiplyD" />
<property name="MFragile" />
<property name="LastEvaluationDate" type="date" />
<property name="ReviewDate" type="date" />
<property name="BeginDate" type="date" />
<property name="EndDate" type="date" />
<property name="EventCode" />
<property name="WrittenConsentDate" type="date" />
</joined-subclass>
</class>
</hibernate-mapping>
Примечания стороны:
- Лучше избегать составного ключа, если это возможно. Или сопоставьте их как компонент, переопределите
GetHashCode
а такжеEquals
для них,... - Нет необходимости дублировать имена свойств в качестве имен столбцов, если они совпадают. И большинство типов свойств могут быть выведены из базового класса NHibernate. Если они совпадают, лучше не раздувать ваше отображение, указав их тип в отображении. (Таким образом, я оставил только длины строк в моем примере выше и тип даты, поскольку нет точного соответствия между типами даты и времени.Net и SQL).
- Странно "переназначать" ваш первичный ключ как свойства в подклассе. Вы должны наследовать эти свойства от базового класса
<id>
и поэтому вам больше не нужно отображать их снова в присоединенном подклассе. - Отключение
lazy
загрузка не является обычной практикой с NHibernate. Ленивая загрузка с NHibernate может принести выгоду от пакетных загрузок, которые делают ее довольно эффективной. Смотрите мой ответ здесь для более подробной информации.
Хотя с составными ключами вы должны отобразить их как компоненты для преодоления ленивых нагрузок. (В противном случае доступ к одному из свойств ключа на незагруженном прокси приведет к его загрузке.)