Недопустимое свойство подкласса 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 может принести выгоду от пакетных загрузок, которые делают ее довольно эффективной. Смотрите мой ответ здесь для более подробной информации.
    Хотя с составными ключами вы должны отобразить их как компоненты для преодоления ленивых нагрузок. (В противном случае доступ к одному из свойств ключа на незагруженном прокси приведет к его загрузке.)
Другие вопросы по тегам