是否可以用NHibernate急切地加载外自然键?

本文关键字:加载 自然 NHibernate 是否 | 更新日期: 2023-09-27 18:04:52

例如,假设我有两个表,ProductOrder。产品有IDNameDescriptionCost等详细栏目。Order有IDProductID列(假设一个Order只能包含一个产品)。

当在系统中显示订单列表时,我还想显示关联的产品名,而不显示所有其他数据(即,急切加载订单及其关联的产品名,并惰性加载所有其他产品属性):

SELECT o.ID, o.ProductID, p.Name FROM Order o JOIN Product p ON o.ProductID=p.ID

如果我在NHibernate中这样做,我有两个选择:即时加载或延迟加载。

在急切加载中,我得到了这样的东西:

SELECT o.ID, o.ProductID, p.ID, p.Name, p.Description, p.Cost, p.... FROM Order JOIN Product p ON o.ProductID=p.ID

使用延迟加载,我得到如下内容:

SELECT o.ID, o.Product ID from Order
....
SELECT p.Name, p.Description, p.Cost, p.... FROM Product p WHERE p.ID=?

这里有一个更具体的例子,说明我正在努力实现的目标。我正在使用现有的DAL并试图集成NHibernate。当前DAL的功能之一是,它允许检索一些基本的外键信息,作为父记录的一部分。假设有一个User表和一个Region表。每个用户都有一个指向其所在区域的外键。在GUI中显示用户信息时,地区名称应与用户一起显示,但不需要显示该地区的其他详细信息。

在当前DAL中,User域对象有一个类型为ForeignKeyReference<Region>的成员。

public class ForeignKeyReference<T>
{
    public virtual int ForeignKeyID { get; set; }
    public virtual string ForeignNaturalKey { get; set; }
    public virtual T Reference { get; set; }
}

当从数据库中检索User时,也检索Region的主键和自然键,并将Reference设置为代理对象。我想用NHibernate来简化这个,但仍然保持这个功能。例如,我想删除ForeignKeyReference<Region>成员,只拥有一个Region成员,这是一个NHibernate代理。在这个代理上,我希望能够检索ID和Name,而不必再次访问数据库。

是否可以用NHibernate急切地加载外自然键?

可以将特定列标记为惰性列。Ayende去年写过这个新功能。

尽管如此,我还是建议您阅读有关此特性的Hibernate文档:

Hibernate3支持延迟获取单个属性。这优化技术也称为取组。请注意这主要是一种营销功能;优化行读取要复杂得多比优化列读取更重要。但是,只有加载类的某些属性在极端情况下可能很有用。为例如,当遗留表有数百列和数据时模型无法改进

另一种选择是创建您自己的查询:

Session.CreateQuery

看一下这个答案