如何避免NHibernate中不必要的连接

时间:2010-10-05 23:02:55

标签: nhibernate nhibernate-mapping

我有一个名为'Entity'的课程,可以是个人或组织。我有一些其他类是Entity的后代,它们的属性在我的数据库的扩展表中定义。我的一个后代被命名为“用户”。

我的表格结构的一个真正截断的例子:

Table: ENTITY
Id - UniqueIdentifier
LastName - Varchar(200)
FirstName - Varchar(50)

Table: USER
Id - UniqueIdentifier (FK to Entity)
Password - Varchar(20)

使用NHibernate.Linq,我获取一个非用户实体的实例,如下所示:

Session.Get<Entity>(myIdValue);

生成的SQL始终加入扩展表,并包含扩展表中的其他列。

当我要求实体的实例时,我真的不想要它的一个后代。

有人能指出我的错误吗?

根据大众需求,这里是我引用的实体类层次结构的映射文件:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <!-- AbstractEntity -->
  <class xmlns="urn:nhibernate-mapping-2.2" name="netfile.model.filer.entities.AbstractEntity, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Entity" abstract="true" discriminator-value="AbstractEntity">
    <id name="Id" type="System.Guid">
      <column name="Id" />
      <generator class="guid.comb" />
    </id>
    <discriminator column="Type" type="string"/>
    <property name="Xref">
      <column name="Xref" />
    </property>
    <property name="Name">
      <column name="LastName" />
    </property>
    <property name="FiledAs">
      <column name="FiledAs" />
    </property>
    <property name="RestKey">
      <column name="RestKey" />
    </property>
    <property name="SearchText">
      <column name="SearchText" />
    </property>
    <many-to-one class="netfile.model.filer.dataspaces.Dataspace, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Dataspace">
      <column name="Dataspace_id" />
    </many-to-one>
    <many-to-one class="netfile.model.filer.Ownership, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Ownership">
      <column name="Ownership_id" />
    </many-to-one>
    <bag name="Descriptions" cascade="all-delete-orphan" inverse="true">
      <key>
        <column name="Entity_Id" />
      </key>
      <one-to-many class="netfile.model.filer.descriptions.AbstractDescription" />
    </bag>
    <!-- All Concrete Entity Types (Org, Ind, etc) -->
    <subclass name="netfile.model.filer.entities.Entity, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="Entity">
      <property name="FirstName">
        <column name="FirstName" />
      </property>
      <property name="IsIndividual">
        <column name="IsIndividual" />
      </property>
      <property name="IsLobbyistClient">
        <column name="IsLobbyistClient" />
      </property>
      <property name="MiddleName">
        <column name="MiddleName" />
      </property>
      <property name="Prefix">
        <column name="Prefix" />
      </property>
      <property name="Suffix">
        <column name="Suffix" />
      </property>
      <property name="Occupation">
        <column name="Occupation" />
      </property>
      <bag name="ContactMethods" cascade="all" inverse="true">
        <key>
          <column name="Entity_Id" />
        </key>
        <one-to-many class="netfile.model.common.OneLineAddress, netfile.model.common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bag>
      <many-to-one cascade="all" class="netfile.model.common.AddressUS, netfile.model.common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="BusinessAddress">
        <column name="BusinessAddress_id" />
      </many-to-one>
      <many-to-one cascade="all" class="netfile.model.common.AddressUS, netfile.model.common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="MailingAddress">
        <column name="MailingAddress_id" />
      </many-to-one>
      <many-to-one cascade="all" class="netfile.model.common.AddressUS, netfile.model.common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="DisclosureAddress">
        <column name="DisclosureAddress_id" />
      </many-to-one>
      <many-to-one class="netfile.model.filer.entities.Entity, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="Employer">
        <column name="Employer_id" />
      </many-to-one>
      <!-- Organization, Agency -->
      <!-- Agency -->
      <subclass name="netfile.model.filer.entities.Agency, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="Agency">
        <join table="Entity_Agency">
          <key>
            <column name="Entity_id" />
          </key>
          <property name="Abbreviation">
            <column name="Abbreviation" />
          </property>
          <many-to-one cascade="save-update" class="netfile.model.filer.entities.Entity, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="TechnicalSupportContact">
            <column name="TechnicalSupportContact_id" />
          </many-to-one>
        </join>
      </subclass>
      <!-- Committee -->
      <subclass name="netfile.model.filer.entities.campaign.Committee, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="Committee">
        <join table="Entity_Committee">
          <key>
            <column name="Entity_id" />
          </key>
          <property name="FilerId">
            <column name="FilerId" />
          </property>
        </join>
        <!-- GeneralPurposeCommittee -->
        <subclass name="netfile.model.filer.entities.campaign.GeneralPurposeCommittee, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="GeneralPurposeCommittee">
        </subclass>
        <!-- ControlledCommittee -->
        <subclass name="netfile.model.filer.entities.campaign.ControlledCommittee, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="ControlledCommittee">
          <bag name="ControllingOfficers" table="Entity_Links">
            <key>
              <column name="Source_Id" not-null="true"/>
            </key>
            <many-to-many class="netfile.model.filer.entities.Entity, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
              <column name="Target_Id" not-null="true"/>
            </many-to-many>
          </bag>
          <!-- PrincipalCampaignCommittee -->
          <subclass name="netfile.model.filer.entities.campaign.PrincipalCampaignCommittee, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="PrincipalCampaignCommittee">
          </subclass>
        </subclass>
      </subclass>
      <!-- User -->
      <subclass name="netfile.model.filer.entities.User, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="User">
        <join table="Entity_User">
          <key>
            <column name="Entity_id" />
          </key>
          <property name="ChallengeAnswer">
            <column name="ChallengeAnswer" />
          </property>
          <property name="ChallengeQuestion">
            <column name="ChallengeQuestion" />
          </property>
          <property name="Disabled">
            <column name="Disabled" />
          </property>
          <property name="Password">
            <column name="Password" />
          </property>
          <property name="PasswordResetKey">
            <column name="PasswordResetKey" />
          </property>
          <property name="Reference">
            <column name="Reference" />
          </property>
          <property name="SecurityLocked">
            <column name="SecurityLocked" />
          </property>
          <bag name="DataspacePermissions" cascade="all">
            <key>
              <column name="User_Id" />
            </key>
            <one-to-many class="netfile.model.filer.permissions.PermissionDataspace, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
          </bag>
        </join>
        <subclass name="netfile.model.filer.entities.UserSupport, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="UserSupport">
          <join table="Entity_UserSupport">
            <key>
              <column name="Entity_id" />
            </key>
            <property name="CompanyName">
              <column name="CompanyName" />
            </property>
          </join>
        </subclass>
      </subclass>
    </subclass>
    <!-- MunicipalDecision, MunicipalDecisionSfo -->
    <subclass name="netfile.model.filer.entities.lobbyist.MunicipalDecision, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="MunicipalDecision">
      <join table="Entity_MunicipalDecision">
        <key>
          <column name="Entity_id" />
        </key>
        <property name="Description">
          <column name="Description" />
        </property>
        <property name="OutcomeSought">
          <column name="OutcomeSought" />
        </property>
      </join>
    </subclass>
    <!-- MunicipalDecisionSfo -->
    <subclass name="netfile.model.filer.entities.lobbyist.sfo.MunicipalDecisionSfo, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" discriminator-value="MunicipalDecisionSfo">
      <join table="Entity_MunicipalDecision">
        <key>
          <column name="Entity_id" />
        </key>
        <property name="Description">
          <column name="Description" />
        </property>
        <property name="OutcomeSought">
          <column name="OutcomeSought" />
        </property>
        <property name="FileNumber">
          <column name="FileNumber" />
        </property>
        <many-to-one class="netfile.model.filer.settings.ownership.AgencyDefinedLobbyingSubjectArea, netfile.data.filer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="SubjectArea">
          <column name="SubjectArea_id" />
        </many-to-one>
      </join>
    </subclass>
  </class>
</hibernate-mapping>

4 个答案:

答案 0 :(得分:3)

您的错误是您的数据库设计不佳。您正在使用每子类表映射策略,但您已将其应用于许多明显不相关的类。组织如何拥有名字或姓氏?

当你得到一个实体时,NHibernate必须连接继承树中的所有表,因为它不知道返回什么样的具体类型。如果您获得用户或组织,它将只按预期加入另一个表。

实体是抽象类吗?您无法获取Entity类型的具体对象,因为无法构造抽象类。

编辑添加:看到映射文件后,我真的认为你应该重新考虑你的设计。这不是对继承的良好或合理使用。如果你真的想继续这个模型,我会建议保留抽象基类但不映射它。但我认为这种设计存在更深层次的问题。

答案 1 :(得分:2)

Polymorphism =“explicit”应该被放入我的类声明中。 NHMNnate中默认隐含多态性。

答案 2 :(得分:0)

没有进行连接,NHibernate不知道返回用户或实体实例。你无法避免这种加入。保存用户时,您将返回一个用户。如果您不想“取回用户”,则可以保存实体而不是用户。

答案 3 :(得分:-1)

您必须告诉配置文件您想要lazy-loading


卫生署。事实证明,当我回答时,我并没有正确地醒着:)

我搜索了一下这个主题并且可以通过mookid指出你this article(我猜他是here on SO too)那确认了Jamie Ides所说的是什么,基本上你可能在这里有代码味道。也许重新考虑这些类及其映射可能是一个更好的主意。