Nhibernate 使用鉴别器时避免选择+1

Nhibernate 使用鉴别器时避免选择+1,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我用鉴别器来处理物品状态。我正在使用NHibernate分析器,并注意到我的应用程序在选择我的州时变得非常疯狂。我总共有8个州,NHibernate一直这样询问: SELECT state0_.State_id as State1_10_0_, state0_.Name as Name10_0_ FROM States state0_ WHERE state0_.State_id = **3** /* @p0 */ 触发选择+1的是当

我用鉴别器来处理物品状态。我正在使用NHibernate分析器,并注意到我的应用程序在选择我的州时变得非常疯狂。我总共有8个州,NHibernate一直这样询问:

SELECT state0_.State_id         as State1_10_0_,
       state0_.Name             as Name10_0_
FROM   States state0_
WHERE  state0_.State_id = **3** /* @p0 */
触发选择+1的是当我选择状态等于1、2、3、4或5的所有项目时。这将为我的项目发出一个查询,同时为每个状态发出5个查询。因为我经常查询状态为的项,所以我执行了大量的查询

现在,看看分析器,我不确定这是否是一个很大的问题,因为我查询的第一个状态需要6毫秒才能查询,6毫秒才能实现。所有其他状态显示为以0毫秒进行查询,以0毫秒进行具体化。NHibernate探查器仍将此显示为臭名昭著的SELECT+1问题

从我的聚合根映射中,我有:

        References(x => x.State)
            .Not.Nullable()
            .Not.LazyLoad();
        Id(x => x.Id, "State_id").GeneratedBy.Assigned();
        Map(x => x.Name).Not.Nullable();

        DiscriminateSubClassesOnColumn("State_id");
对于我的状态鉴别器映射,我有:

        References(x => x.State)
            .Not.Nullable()
            .Not.LazyLoad();
        Id(x => x.Id, "State_id").GeneratedBy.Assigned();
        Map(x => x.Name).Not.Nullable();

        DiscriminateSubClassesOnColumn("State_id");
关于歧视者有什么我不理解的吗

以下是导致问题的查询:

var items =
    session.QueryOver(() => itemAlias)
        .SelectList(x => x
                             .Select(xx => xx.Id).WithAlias(() => sentTo.Id)
                             .Select(xx => xx.State).WithAlias(() => sentTo.State)
                             .Select(xx => xx.Status).WithAlias(() => sentTo.Status)
        )
        .JoinAlias(() => itemAlias.State, () => stateAlias)
        .WhereRestrictionOn(() => stateAlias.Id).IsInG(filters)
        .Where(() => itemAlias.Status == Status.InProgress)
        .TransformUsing(Transformers.AliasToBean<SentToDto>())
        .List<SentToDto>();
要解决我的SELECT+1问题,我只需要通过鉴别器对象列表而不是单个id进行查询

.Where(() => itemAlias.State.IsIn(new []{State.FooState, State.BarState}))

听起来您急于加载状态本身,因此您的第一个查询类似于:

SELECT * FROM Items where StateID IN (1,2,3,4,5)
然后有五个查询,每个州一个查询:

SELECT Name FROM State WHERE StateID = 1
SELECT Name FROM State WHERE StateID = 2
....

为了避免这种情况,您应该在第一次查询中指定从项目到状态的连接,以便在那里获得名称,否则,如果您不需要结果中的标识符以外的其他信息,请将状态对象设置为延迟加载。

您能提供查询代码吗?