对休眠 n+1 警报消息感到困惑

Posted

技术标签:

【中文标题】对休眠 n+1 警报消息感到困惑【英文标题】:confused about nhibernate n+1 alert message 【发布时间】:2012-05-30 11:24:03 【问题描述】:

在我的查询中,我试图选择所有实体(其中 20 个)并像这样遍历集合

List<Domain.Property> data = session.Query<Domain.Property>().ToList();

PropertyViewModel viewModel;
List<PropertyViewModel> listOfViewModels = new List<PropertyViewModel>();

foreach (Domain.Property prop in data)

    viewModel = new PropertyViewModel()
    
        AdType = prop.AdType.ToString(), 
        CityName = prop.CityName, 
        ContructionYear = prop.ConstructionYear, 
        Photo = prop.Photos.First()

    ;

listOfViewModels.Add(viewModel);

每个属性必须有一张或多张照片,我只需要第一张,所以我使用 Photos.First()

当这一行被注释掉时 Photo = prop.Photos.First() nhib。分析器报告加载了 20 个实体,这很好(来自第一个查询的实体)。

但是使用 Photo = prop.Photos.First() 加载的实体增加到 65 个实体,该数量应该约为。等于属性+照片集。

谁能指出正确的方向?

在 nhib 中。生成的sql里面有

SELECT photos0_.PropertyId    as PropertyId1_,
       photos0_.Id            as Id1_,
       photos0_.Id            as Id1_0_,
       photos0_.ImageData     as ImageData1_0_,
       photos0_.ImageMimeType as ImageMim3_1_0_,
       photos0_.PropertyId    as PropertyId1_0_
FROM   Photo photos0_
WHERE  photos0_.PropertyId = 117 /* @p0 */

标记为 SELECT N+1

【问题讨论】:

【参考方案1】:

对于每个属性(获取它们列表的单个查询),您正在执行另一个查询以获取第一张照片。 Photos 集合在您尝试访问它之前不会填充,从而导致第二次查询。

作为原始查询的一部分加入照片表,以将其减少为单个查询。

【讨论】:

或者在照片集合的映射中设置一个非零的批量大小,以使 NHibernate 一次为多个所有者初始化集合。 @Michael Shimmins 但如果我在第一个查询中使用 List data = session.Query().Fetch(x=>x.Photos).ToList ();我会获取所有的收藏,我只需要第一个 第一张照片对你有什么特别的意义吗?您现在加载第一张照片的方式将使用 SQL 服务器的自然排序顺序选择第一张照片,从长远来看,这可能不是您需要的。 我只需要第一张照片,因为这就是我在那个 viewModel 中使用的,没有其他地方可以减少加载时间。 @Michael Shimmins 你能展示加入照片对象的例子吗

以上是关于对休眠 n+1 警报消息感到困惑的主要内容,如果未能解决你的问题,请参考以下文章

ORM 和 DAO 设计模式

使用注解或使用休眠配置文件休眠

对系统日志消息格式感到困惑

休眠用户消息关系

休眠没有找到具有该名称的@NamedStoredProcedureQuery

系统休眠消息PBT_APMSUSPEND