我有一个父子关系,在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)
)
这很好,我认为:
所以我有一部电话,它可以不带任何细节,并且当我需要时,我只能添加一个细节来完成我的对象,而我不想总是加载其他细节。
如何在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" />
答案 0 :(得分:0)
可空为空的一对一对象无法知道而不查询关联表是否存在,因此,为了加载其代理,需要查询关联表。从这一点出发,在过去的讨论中已经知道,查询整个状态而不是仅查询键会更好,因此急于加载。 ->您将无法在非强制性的引用上启用延迟加载。至少没有标准解决方案。
如果您希望该关系能够延迟加载PhoneDetails
,则必须使其成为强制性/不可为空。
您也可以将PhoneDetails
中的属性标记为lazy="true"
。因此,一旦您加载父实体,就将访问该表并为PhoneDetail
对象创建一个代理,但是标记为lazy="true"
的所有属性仅在您访问它们后立即加载。
请注意,访问其中之一的所有带有lazy="true"
的属性都会被加载
答案 1 :(得分:0)
根据此SO答案,非强制性一对一关系不支持延迟加载。
因此,为了解决此问题,为什么不摆脱这种一对一的关系呢?
如果您90%的时间不需要详细信息,我会考虑删除关系关系,并使用单独的存储库方法,该方法只能使您检索指定PhoneDetails
的{{1}}。>
要继续您的示例,我将得出以下结论:
Phone