获得NHibernate选择N + 1

时间:2016-08-03 16:21:48

标签: c#-4.0 nhibernate fluent-nhibernate queryover

我是NHibernate的新手。当我从NHibernate Profiler测试我的查询时,我收到了Select N + 1警告。我不确定我的映射或查询是做错了什么。

基本上我有一个名为Header的表,它有很多细节。对于每个细节,我有一个重播。即

一个标题 - >许多细节 一个细节 - >一个重播

查询:

    var query = _session.QueryOver(() => headerAlias)
                    .Where(() => headerAlias.ScriptNumber == scriptId)
                    .And(() => headerAlias.ChannelCode == channelId)
                    .Future<ProgramHeader>();

我的映射:

public ProgramHeaderMap()
{
    Table("S_IDB_M_PROG_HDR");

    CompositeId()
        .KeyProperty(x => x.ScriptNumber, "PROGCD")
        .KeyProperty(x => x.ChannelCode, "CHCD");

    Map(x => x.ChannelCode).Column("CHCD");
    Map(x => x.ShowCode).Column("SHOWCD");
    Map(x => x.ShowStartTime).Column("ONAIRSTART");
    Map(x => x.ShowEndTime).Column("ONAIREND");
    Map(x => x.Presenters).Column("HOST");
    Map(x => x.Guests).Column("GUEST");
    Map(x => x.Planners).Column("PLANNER");
    Map(x => x.ModifiedTime).Column("UPDDATE");

    HasMany(x => x.Pal)
            .AsBag()
            .Inverse()
            .KeyColumns.Add("PROGCD", "CHCD")
            .Cascade.All()
            .Not.LazyLoad();
}

DetailMap:

public ProgramDetailMap()
{
    Table("S_IDB_M_PROG_DTL");

    CompositeId()
        .KeyProperty(x => x.ScriptNumber, "PROGCD")
        .KeyProperty(x => x.ChannelCode, "CHCD")
        .KeyProperty(x => x.ProductNumber, "PRODCD")
        .KeyProperty(x => x.ColorCode, "COLORCD")
        .KeyProperty(x => x.SizeCode, "SIZECD");

    Map(x => x.PromoCode,"PCPARAM1");
    Map(x => x.EasyPayInstalments,"EZINST");
    Map(x => x.EasyPayFirstAmount,"EZAMT");
    Map(x => x.EasyPayNextAmount,"EZAMT2");
    Map(x => x.UpdatedDate).Column("UPDDATE");

    References(x => x.ProgramHeader)
        .Columns("PROGCD", "CHCD")
        .LazyLoad();

    References(x => x.Replay)
        .Columns("PROGCD", "CHCD", "PRODCD", "COLORCD", "SIZECD")
        .NotFound.Ignore();
}

}

重播:

public ProgramReplayMap()
{
    Table("S_IDB_M_PROG_REPL");

    CompositeId()
        .KeyProperty(x => x.ScriptNumber, "PROGCD")
        .KeyProperty(x => x.ChannelCode, "CHCD")
        .KeyProperty(x => x.ProductNumber, "PRODCD")
        .KeyProperty(x => x.ColorCode, "COLORCD")
        .KeyProperty(x => x.SizeCode, "SIZECD");

    Map(x => x.Price, "REC_PRICE");
    Map(x => x.Postage, "REC_POSTAGE");
    Map(x => x.UpdatedDate).Column("UPDDATE");
}

感谢此查询的一些回复。

由于

1 个答案:

答案 0 :(得分:0)

您想要的起点是启用批量提取。文档位于http://nhibernate.info/doc/nhibernate-reference/performance.html#performance-fetching-batch

在FluentNHibernate中,它可用作ClassMap和集合映射上的.BatchSize()方法。

批量提取意味着NHibernate可以一次性获取相同类型的大量相关实例。例如,如果您已经加载了20个A实例,每个实例都持有对B的延迟引用,则只要您访问其中一个B实例,NHibernate就可以使用一个查询加载所有20个B实例。假设如果您访问其中一个引用的B实例,很可能您很快就会访问其他实例,并且使用相同查询加载20个实例的速度非常快以至于无关紧要如果我们碰巧加载了一些实际上不需要的东西。 (数字20是您使用批量大小设置控制的。)