Я использую дискриминаторы для обработки состояний элементов. Я использую 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, мне просто нужно запросить список объектов-дискриминаторов, а не отдельных идентификаторов.
.Where(() => itemAlias.State.IsIn(new []{State.FooState, State.BarState}))