【发布时间】:2012-02-07 01:24:00
【问题描述】:
我正在使用鉴别器来处理项目状态。我正在使用 NHibernate Profiler 并注意到我的应用程序在选择我的状态时非常疯狂。我总共有 8 个状态,NHibernate 一直这样查询:
SELECT state0_.State_id as State1_10_0_,
state0_.Name as Name10_0_
FROM States state0_
WHERE state0_.State_id = **3** /* @p0 */
触发此 SELECT+1 的原因是当我选择状态等于 1、2、3、4 或 5 的所有项目时。这将为我的项目发出一个查询,并且为每个状态发出 5 个查询。因为我经常查询项目(有状态),所以我执行了大量的查询。
现在,看看探查器,我不确定这是否是一个很大的问题,因为我查询的第一个状态需要 6 毫秒来查询和 6 毫秒来实现。所有其他状态显示为查询时间为 0 毫秒,具体化时间为 0 毫秒。 NHibernate Profiler 仍然将此显示为臭名昭著的 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");
关于鉴别器有什么我不理解的地方吗?
这是导致问题的查询:
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>();
解决方案
罪魁祸首是
.WhereRestrictionOn(() => stateAlias.Id).IsInG(filters)
要解决我的 SELECT+1 问题,我只需要通过鉴别器对象列表而不是单个 id 进行查询。
.Where(() => itemAlias.State.IsIn(new []{State.FooState, State.BarState}))
【问题讨论】:
-
能否提供您的查询码?
标签: nhibernate fluent-nhibernate