我在主题中说过Fluent NHibernate,但我认为这是一个NHibernate问题。但是,我不想通过遗漏细节来混淆事情。
我正在使用Fluent NHibernate 1.0.0.593和NHibernate 2.1.0.4000。
首先是一点背景......
我有一个基类,有三个实现类,我试图使用DiscriminateSubClassesOnColumn / SubclassMap.DiscriminatorValue Fluent NHibernate语法进行映射。子类表示我可以从三个不同的第三方数据提供者获得的响应。信息大致相同,但关系不同(一个响应类型可以有多个地址,另一个只能有一个,等等)。
我让Fluent NHibernate提取它生成的NHibernate配置xml,并根据我对鉴别器和子类块应该是什么样的理解,配置似乎正在生成(这就是为什么我认为这是一个NHibernate问题,不是流利的NHibernate)。
我看到的“问题”是,对于来自数据库的初始查询,NHibernate似乎正在扫描子类并将所有一对一关系作为初始查询中的连接进行。由于某些子类具有与一对多关系相同的子类型,因此当我尝试检索这些其他类型之一时,这会导致错误。
我将发布生成的NHibernate配置以供参考。
任何人对如何控制这个或者我做错了有什么想法?
感谢。
答案 0 :(得分:0)
<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>
答案 1 :(得分:0)
不确定这是最好的答案,所以我仍然有兴趣听取其他想法,但我发现一个修复。
将Fetch.Select添加到子类上的任何HasOne关系,似乎强制对这些子类型的查询始终位于单独的SELECT中。在连接会更好的情况下,它最终效率会降低,但它会使异常消失。