2016-05-04 3 views
0

Я пытаюсь решить эту проблему, когда подкласс содержит набор свойств, однако два свойства не существуют в ссылочной таблице.NHiberate Подключенный подкласс Недопустимое свойство

Эти два свойства существуют в таблице расширения, которая имеет FKs обратно в базовую таблицу. Я не знаю, как изменить этот xml для поддержки первого объединенного подкласса и добавления другого соединения для таблицы Extension.

Я попытался просто добавить еще один объединенный подкласс для таблицы 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, где они не существуют. Они действительно существуют в таблице Extension.

Я не уверен, как изменить этот 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'. Список ожидаемых элементов: свойство, много-к-одному, один-к-одному, компонент, динамический компонент, свойства, любой, карта, набор, список, сумка, суммарная сумка, массив, примитивный массив, объединенный подкласс , загрузчик, 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, поэтому вам придется использовать его в базовом классе, если вы можете добавить к ним эти свойства. Настройка вашего Pastebin отображения, связанный с комментарием:

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

Боковые ноты:

  • Лучше избежать составной ключ, если это возможно. Или скопируйте их как: component, override GetHashCode и Equals для них, ...
  • Нет необходимости дублировать имена свойств как имена столбцов, если они одинаковы. И большинство типов свойств можно вывести из базового класса NHibernate. Если они совпадают, лучше не раздувать ваше сопоставление, указав их тип в сопоставлении. (Таким образом, в моем примере выше и типе даты я оставил только длины строк, так как нет точного совпадения между .Net date & типами времени и SQL.)
  • Странно «переназначить» ваш первичный ключ как свойства в подклассе. Вы должны наследовать эти свойства из базового класса <id>, и поэтому вам не нужно будет снова сопоставлять их в объединенном подклассе.
  • Отключение lazy Загрузка не является обычной практикой с NHibernate. Ленивая загрузка с NHibernate может принести выгоду от пакетных нагрузок, которые делают ее достаточно эффективной. Для получения более подробной информации см. Мой ответ here.
    Хотя с составными клавишами, вы должны сопоставить их как компоненты для наилучших ленивых нагрузок. (В противном случае доступ к одному из свойств ключа для разгруженного прокси-сервера приведет к его загрузке.)
+0

Большое спасибо за ввод. Плохо то, что я считаю, что забыл упомянуть, что эти два поля существуют в классе, который указан в объединенном классе - SESProgramAssociation. Проблема связана с различными стандартами для реализации, я не могу изменить класс SESProgramAssociation, чтобы, скажем, удалить эти поля и создать отдельный класс для этого объекта. Мне нужно как-то повторно использовать SESProgramAssociation, но только эти два поля и относить это к таблице расширений .... надеюсь, это имеет смысл. –

+0

Тогда мое третье предложение - это путь для вас, используйте '' отображение внутри '' для сопоставления двух других свойств. –

+0

Дал попытку, но получил ошибку, обновил OP. Ссылка на полный файл сопоставления, который может помочь при отладке: http://pastebin.com/ybSKHDsG –

Смежные вопросы