首页 文章

NHiberate加入子类无效的属性

提问于
浏览
0

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

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

我试图简单地为Extension表添加另一个join-subclass,但是由于类名相同,映射无效 .

<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 . 它们实际上存在于Extension表中 .

我不确定如何修改此xml以将这些字段指向Extension表,因此生成的查询实际上从该表中提取它们而不是错误的表 . 非常感谢任何帮助,这是我对NHiberate的第一次体验,不用说,这不是很有趣!

根据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,数组,原始数组,连接子类,loader,sql-insert,sql-update,sql-delete,resultset,query,sql-query'innamespace'瓮:nhibernate-mapping-2.2' .

1 回答

  • 1

    您的第二个表不应映射为另一个 joined-subclass ,因为它与您的域模型中的子类不匹配 .

    它应该映射为独立的 Extension 实体,扩展实体将其引用为one-to-one相关实体 .

    或者,您可以使用join映射在域模型中拥有单个实体 . 但 subclass 上不允许 join 映射,因此如果可以添加这些属性,则必须在基类上使用它 . 调整在注释中链接的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,为它们覆盖 GetHashCodeEquals ,...

    • 如果列名相同,则不需要复制属性名称 . 大多数属性类型都可以通过NHibernate从底层类推断出来 . 如果它们匹配,最好不要通过在映射中指定它们的类型来膨胀映射 . (所以我在上面的示例中只留下了字符串长度和日期类型,因为.Net日期和时间类型与SQL之间没有精确匹配 . )

    • "remap"您的主键作为子类中的属性很奇怪 . 您应该从基类 <id> 继承这些属性,因此您不需要在连接的子类中再次映射它们 .

    • 禁用 lazy 加载对于NHibernate来说并不常见 . 使用NHibernate进行延迟加载可以获得批量加载,这使得它非常有效 . 有关详细信息,请参阅我的回答here .
      虽然使用复合键,但您应该将它们映射为最佳延迟加载的组件 . (否则,访问卸载的代理上的某个键属性将导致它加载 . )

相关问题