NHibernate具有一个延迟加载

时间:2018-09-04 15:40:57

标签: hibernate nhibernate fluent-nhibernate lazy-loading nhibernate-mapping

我有一个父子关系,在Sql Server上只有一个孩子。 该子项包含我不会加载的胖Blob数据。 子级是可选的,它必须取决于父级的生命周期。 因此,子级上的外键指向父级,并且是唯一的。

我可以在Hibernate参考上使用official示例。

public class Phone
{
    public virtual long Id { get; set; }

    public virtual string Number { get; set; }

    public virtual PhoneDetails Details { get; set; }
}

public class PhoneDetails
{
    public virtual int Id { get; set; }

    public virtual Phone Phone { get; set; }

    public virtual string Provider { get; set; }
}

电话详细信息必须取决于数据库上的父级生命周期。 我可以在sql上使用一对一关系,在子项上使用唯一的外键,也可以在简单的外键(例如,示例)中加上唯一约束,使用多对一关系。

CREATE TABLE Phone (
    id BIGINT IDENTITY PRIMARY KEY,
    number VARCHAR(255)
)

CREATE TABLE PhoneDetails (
    id BIGINT IDENTITY PRIMARY KEY,
    phone_id BIGINT UNIQUE FOREIGN KEY REFERENCES dbo.Phone(id),
    provider VARCHAR(255)        
)

这很好,我认为:

enter image description here

所以我有一部电话,它可以不带任何细节,并且当我需要时,我只能添加一个细节来完成我的对象,而我不想总是加载其他细节。

如何在NHibernate 5上映射这些类? 似乎我需要双向使用HasOne,但是在那种情况下,我不能使用延迟加载,因此在Phone上进行的每个简单查询都会导致联接并选择详细信息的所有字段。

我使用明细表存储90%的时间都不需要的巨大元数据,但是现在我尝试加载Phone的每个地方,查询也加载了巨大的细节,这真的很糟糕。 / strong>

那么我可以通过哪种方式映射这种关系?

一个父母和一个孩子,其中包含无用的脂肪数据。 在sql中,我认为该结构还可以,因为我不希望有更多的孩子,而是希望他们生活在父母的陪伴下(因此,孩子的FK)。

不可能管理这种类型的关系,我在哪里错?数据库设计?映射?

这是我使用的映射:

  <class name="Phone" table="Phone">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="Number"/>
    <one-to-one name="PhoneDetails" class="PhoneDetails"/>
  </class>

  <class name="PhoneDetails" table="PhoneDetails">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="Provider" />
    <many-to-one name="Phone" column="phone_id" unique="true"/>    
  </class>

我还尝试了第二种选择,在关系模型上使用外键\主键(因此我删除了FK并使用了与PK \ FK相同的ID),并在子级中使用了此映射:

   <one-to-one name="Phone" class="Phone" constrained="true" />

2 个答案:

答案 0 :(得分:0)

可空为空的一对一对象无法知道而不查询关联表是否存在,因此,为了加载其代理,需要查询关联表。从这一点出发,在过去的讨论中已经知道,查询整个状态而不是仅查询键会更好,因此急于加载。 ->您将无法在非强制性的引用上启用延迟加载。至少没有标准解决方案。

如果您希望该关系能够延迟加载PhoneDetails,则必须使其成为强制性/不可为空。

您也可以将PhoneDetails中的属性标记为lazy="true"。因此,一旦您加载父实体,就将访问该表并为PhoneDetail对象创建一个代理,但是标记为lazy="true"的所有属性仅在您访问它们后立即加载。 请注意,访问其中之一的所有带有lazy="true"的属性都会被加载

答案 1 :(得分:0)

根据此SO答案,非强制性一对一关系不支持延迟加载。

因此,为了解决此问题,为什么不摆脱这种一对一的关系呢? 如果您90%的时间不需要详细信息,我会考虑删除关系关系,并使用单独的存储库方法,该方法只能使您检索指定PhoneDetails的{​​{1}}。

要继续您的示例,我将得出以下结论:

Phone