2

我有一个具有多个多对一关系的实体,我发现我可以在一个查询中急切地获取它们,如下所示:

public Accommodation GetEager(int id)
{
    IList<Accommodation> query = NHibernateSession.CurrentFor(NHibernateSession.DefaultFactoryKey)
        .CreateQuery(@"
        select a from Accommodation as a
        left join fetch a.AccommodationType
        left join fetch a.AccommodationUnitType
        left join fetch a.CollectionType
        where a.Id = :id
        ")
        .SetProperties(new {id})
        .SetCacheable(true)
        .List<Accommodation>();

    return query.SingleOrDefault();
}

但是,关系并不总是存在,我已经定义了这样的映射:

mapping.References(x => x.AccommodationUnitType).NotFound.Ignore();

我发现当关系不存在时,NHibernate 会生成第二个 SQL 查询来查找它,大概是因为它发现该属性为空。

我的第一个问题是,如何防止第二个 sql 查询?

我的第二个问题是,有没有一种更简单的方法可以将这个提取到一个查询中?人们希望在一个查询中获取所有内容,而不是为每个多对一关系单独查询(这似乎是默认行为),这似乎是非常基本的行为。

4

1 回答 1

1

你确定你使用NotFound().Ignore()正确吗?这个设置决定了如果有一个无效的外键,NHibernate 会做什么。在这种情况下,NotFound().Ignore()防止抛出 EntityNotFoundException。使用该设置,如果未找到相关对象,则该值将为空。如果您对该关系具有参照完整性,那么您不需要NotFound().Ignore().

您所看到的行为显然是意料之中的,并且众所周知,并且不太可能改变

至于您的第二个问题,我建议始终从延迟加载的默认行为开始,并且仅根据实际性能问题的需要使用急切加载进行优化。延迟加载通常比急切获取更有效,因为 a) 对象可能已经在缓存中(不需要 db 行程)和 b) 通过主键选择非常快。您的三个连接查询的性能很可能比主键的四个选择差。

于 2010-10-13T12:14:59.073 回答