Свободный NHibernate DiscriminateSubClassesOnColumn Issue - PullRequest
1 голос
/ 21 декабря 2009

Я сказал «Свободно NHibernate» в теме, но я думаю, что это вопрос NHibernate. Тем не менее, я не хотел путать вещи, опуская детали.

Я использую Fluent NHibernate 1.0.0.593 с NHibernate 2.1.0.4000.

Сначала немного фона ...

У меня есть базовый класс с тремя классами реализации, которые я пытаюсь отобразить, используя синтаксис Fluent NHibernate DiscriminateSubClassesOnColumn / SubclassMap.DiscriminatorValue. Подклассы представляют ответы, которые я могу получить от трех разных сторонних поставщиков данных. Информация обычно одинакова, но отношения различны (один тип ответа может иметь несколько адресов, другой может иметь только один и т. Д.).

У меня был Fluent NHibernate, который извлекал конфигурацию NHibernate xml, которую он генерировал, и, исходя из моего понимания того, как должны выглядеть блоки дискриминатора и подкласса, конфигурация создается правильно (именно поэтому я думаю, что это NHibernate вопрос, а не свободный NHibernate один).

Проблема, с которой я сталкиваюсь, заключается в том, что для начального запроса из базы данных NHibernate, по-видимому, сканирует подклассы и выполняет все взаимно-однозначные отношения в качестве объединений в начальном запросе. Так как некоторые из подклассов имеют тот же дочерний тип, что и отношение «один ко многим», это вызывает ошибку, когда я пытаюсь получить один из этих других типов.

Я опубликую сгенерированную конфигурацию NHibernate для справки.

У кого-нибудь есть идеи о том, как это контролировать, или, может быть, я не так делаю?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 22 декабря 2009

Не уверен, что это лучший ответ, поэтому мне все еще интересно услышать другие мысли, но я нашел a исправление.

Добавление .Fetch.Select для любых отношений HasOne на подклассах, кажется, заставляет запросы для этих дочерних типов всегда находиться в отдельном SELECT. В конечном итоге он оказывается менее эффективным в тех случаях, когда объединение будет лучше, но исключение исключается.

0 голосов
/ 21 декабря 2009
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" discriminator-value="Unknown" name="PersonValidationResponse, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="PersonValidationResponse">
    <id name="ResponseId" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="pk_ResponseId" />
      <generator class="identity" />
    </id>
    <discriminator type="PersonValidationResponseType, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
      <column name="ResponseType" />
    </discriminator>
    <property name="CreatedBy" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CreatedBy" />
    </property>
    <property name="CreatedDate" type="System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="CreatedDate" />
    </property>
    <many-to-one class="PersonValidationRequest, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Request">
      <column name="fk_RequestId" />
    </many-to-one>
    <subclass name="ResponseTypeAResponse, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="ResponseTypeA">
      <one-to-one cascade="all" class="PersonValidationAddress, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" foreign-key="fk_ResponseId" lazy="false" name="Address" property-ref="Response" />
      <one-to-one cascade="all" class="PersonValidationBiographic, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" foreign-key="fk_ResponseId" lazy="false" name="Biographic" property-ref="Response" />
      <one-to-one cascade="all" class="PersonValidationPhone, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" foreign-key="fk_ResponseId" lazy="false" name="Phone" property-ref="Response" />
      <property name="ResponseStatus" type="ResponseStatus, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="ResponseStatus" />
      </property>
      <property name="RawResponse" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <column name="RawResponse" />
      </property>
      <bag cascade="all-delete-orphan" lazy="false" name="Alerts" table="PersonValidationResponseAlert">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <many-to-many class="PersonValidationAlert, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
          <column name="fk_AlertId" />
        </many-to-many>
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Scores" table="PersonValidationResponseScore">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationScore, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Exceptions" table="PersonValidationResponseException">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationException, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
    </subclass>
    <subclass name="ResponseTypeBResponse, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="ResponseTypeB">
      <one-to-one cascade="all" class="PersonValidationWatchList, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" foreign-key="fk_ResponseId" lazy="false" name="WatchListHit" property-ref="Response" />
      <property name="ResponseStatus" type="ResponseStatus, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="ResponseStatus" />
      </property>
      <property name="RawResponse" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <column name="RawResponse" />
      </property>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Addresses" table="PersonValidationAddress">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationAddress, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Biographics" table="PersonValidationBiographic">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationBiographic, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Phones" table="PersonValidationPhone">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationPhone, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" lazy="false" name="Alerts" table="PersonValidationResponseAlert">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <many-to-many class="PersonValidationAlert, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
          <column name="fk_AlertId" />
        </many-to-many>
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Scores" table="PersonValidationResponseScore">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationScore, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Exceptions" table="PersonValidationResponseException">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationException, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
    </subclass>
    <subclass name="ResponseTypeCResponse, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="ResponseTypeC">
      <property name="ResponseStatus" type="ResponseStatus, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="ResponseStatus" />
      </property>
      <property name="RawResponse" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <column name="RawResponse" />
      </property>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Addresses" table="PersonValidationAddress">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationAddress, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Biographics" table="PersonValidationBiographic">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationBiographic, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="CreditAccounts" table="PersonValidationCreditAccount">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationCreditAccount, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Phones" table="PersonValidationPhone">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationPhone, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="WatchListHits" table="PersonValidationWatchList">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationWatchList, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" lazy="false" name="Alerts" table="PersonValidationResponseAlert">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <many-to-many class="PersonValidationAlert, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
          <column name="fk_AlertId" />
        </many-to-many>
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Scores" table="PersonValidationResponseScore">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationScore, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Exceptions" table="PersonValidationResponseException">
        <key>
          <column name="fk_ResponseId" />
        </key>
        <one-to-many class="PersonValidationException, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
    </subclass>
    <subclass name="UnknownResponse, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="Unknown" />
  </class>
</hibernate-mapping>
...