0

我正在尝试解决这个问题,其中子类包含一组属性,但是引用表中不存在其中两个属性。

这两个属性存在于一个扩展表中,该扩展表具有返回基表的 FK。我不确定如何修改此 xml 以支持第一个加入的子类并为扩展表添加另一个连接。

我试图简单地为扩展表添加另一个连接子类,但是由于类名相同,映射无效。

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

生成的最终查询失败,因为它尝试从不存在的 SESProgramAssociation 表中引用 EventCode 和 WrittenConsentDate。它们实际上存在于扩展表中。

我不确定如何修改此 xml 以将这些字段指向扩展表,以便生成的查询实际上从该表中提取它们而不是错误的。非常感谢任何帮助,这是我第一次体验 NHirate,不用说,这并不好玩!

在 Frédéric 的建议下,我更新了但得到了这个错误:

NHibernate.dll 中出现“NHibernate.MappingException”类型的异常,但未在用户代码中处理

附加信息:EdFi.Ods.Entities.NHibernate.Mappings.SqlServer.StudentProgramAssociationBase.hbm.xml(79,8):XML 验证错误:命名空间“urn:nhibernate-mapping-2.2”中的元素“joined-subclass”无效命名空间“urn:nhibernate-mapping-2.2”中的子元素“join”。预期的可能元素列表:'属性、多对一、一对一、组件、动态组件、属性、任何、映射、集合、列表、包、idbag、数组、原始数组、连接子类,加载器,sql-insert,sql-update,sql-delete,结果集,查询,sql-query'在命名空间'urn:nhibernate-mapping-2.2'中。

4

1 回答 1

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>

旁注:

  • 如果可能,最好避免使用复合键。或将它们映射为组件,覆盖GetHashCodeEquals为它们,...
  • 如果属性名称相同,则无需将属性名称复制为列名称。大多数属性类型都可以通过 NHibernate 从底层类中推断出来。如果它们匹配,最好不要通过在映射中指定它们的类型来使映射膨​​胀。(所以我在上面的示例中只留下了字符串长度和日期类型,因为 .Net 日期和时间类型与 SQL 类型之间没有精确匹配。)
  • 将主键“重新映射”为子类中的属性很奇怪。您应该从基类继承这些属性<id>,因此您不需要在连接的子类中再次映射它们。
  • 禁用lazy加载不是 NHibernate 的常见做法。使用 NHibernate 进行延迟加载可以受益于批量加载,这使得它非常有效。有关更多详细信息,请参阅我的答案。
    尽管使用复合键,但您应该将它们映射为组件以最佳地延迟加载。(否则,访问未加载代理上的关键属性之一将导致它加载。)
于 2016-05-04T23:48:36.483 回答