我有一个具有多个多对一关系的实体,我发现我可以在一个查询中急切地获取它们:
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查询,大概是因为它发现该属性为null。
我的第一个问题是,如何防止第二次SQL查询?
我的第二个问题是,是否有更简单的方法来获取一个查询?看起来非常基本的行为是人们想要在一个查询中获取所有内容而不是每个多对一关系的单独查询(这似乎是默认行为)。
答案 0 :(得分:1)
您确定正确使用NotFound().Ignore()
吗?此设置确定如果存在无效外键,NHibernate将执行的操作。在这种情况下,NotFound().Ignore()
可以防止抛出EntityNotFoundException。使用该设置,如果未找到相关对象,则该值将为null。如果您对此关系具有参照完整性,那么您不需要NotFound().Ignore()
。
您看到的行为是apparently expected and well known and unlikely to change。
关于你的第二个问题,我建议总是从延迟加载的默认行为开始,并且只根据实际性能问题的需要优化加载。延迟加载通常比急切提取更有效,因为a)对象可能已经在缓存中(不需要db跳转)和b)通过主键选择非常快。具有三个连接的查询很可能比主键的四个选择要差。