我们如何在QueryOver中干净地进行分组?我上周要求使用下面的示例解决它,但我必须检查nhibernate发送给SQL的结束查询并从那里找到别名。
subQuery.Select(
Projections.ProjectionList().Add(
Projections.SqlGroupProjection(
"this_0_.Id as idAlias",
$"this_0_.Id, this_0_.StartDate, this_0_.DateCreated, this_0_.PricePerAdult,
this_0_.EmptySeats, reservatio5_.NumberOfParticipants",
new string[] { "idAlias" }, new IType[] { Hibernate.NHibernateUtil.Int32 }))
);
如您所见,分组变量可以在子查询或主查询上完成。我们需要一种方法将reservationAlias.NumberOfParticipants转换为字符串至少。
编辑:添加完整代码
Agent agentAlias = null;
AgentProduct agentProductAlias = null;
Operator operatorAlias = null;
Product productAlias = null;
Session sessionAlias = null;
Slot slotAlias = null;
Reservation reservationAlias = null;
UserReservation userReservationAlias = null;
GroupDiscount groupDiscountAlias = null;
var subQuery = QueryOver.Of<Slot>(() => slotAlias)
.JoinAlias(() => slotAlias.Session, () => sessionAlias)
.JoinAlias(() => sessionAlias.Product, () => productAlias)
.JoinAlias(() => productAlias.Operator, () => operatorAlias)
.Left.JoinAlias(() => sessionAlias.GroupDiscounts, () => groupDiscountAlias)
.Left.JoinAlias(() => slotAlias.Reservation, () => reservationAlias)
.Left.JoinAlias(() => reservationAlias.UserReservations, () => userReservationAlias, () => userReservationAlias.Status != UserReservationStatus.Expired);
if (agentGuid.HasValue)
{
subQuery.JoinAlias(() => productAlias.AgentProducts, () => agentProductAlias)
.JoinAlias(() => agentProductAlias.Agent, () => agentAlias)
.Where(() => agentAlias.Guid == agentGuid.Value);
}
if (operatorGuid.HasValue)
{
subQuery = subQuery.Where(() => operatorAlias.Guid == operatorGuid.Value);
}
if (productGuid.HasValue)
{
subQuery = subQuery.Where(() => productAlias.Guid == productGuid.Value);
}
if (minimumDiscount.HasValue)
{
subQuery.Where(() => groupDiscountAlias.DiscountPercentage >= minimumDiscount.Value);
}
if (bookingQuery.HasValue)
{
if (bookingQuery.Value)
{
subQuery.Where(() => userReservationAlias.Id != null);
}
else
{
subQuery.Where(() => userReservationAlias.Id == null);
}
}
if (from.HasValue)
{
subQuery = subQuery.Where(() => slotAlias.StartDate >= from);
}
if (to.HasValue)
{
subQuery = subQuery.Where(() => slotAlias.StartDate <= to);
}
if (onlyAvailable)
{
//Show slots that's not in cutoff. StartDate > Now + Cutoff
subQuery = subQuery.Where(Restrictions.GtProperty(
Projections.Property(() => slotAlias.StartDate),
Projections.SqlFunction(
"addminutes",
NHibernateUtil.DateTimeOffset,
Projections.Conditional(
Restrictions.Eq(Projections.Property(() => reservationAlias.LastMinuteCutoff), true),
Projections.Constant(0),
Projections.Property(() => productAlias.CutoffOffset)
),
Projections.Constant(DateTimeOffset.UtcNow))));
subQuery.Where(() => reservationAlias.Id == null || reservationAlias.OperatorStatus != ReservationStatus.Rejected);
if (onlyGroupSlots)
{
subQuery.Where(() => userReservationAlias.Id == null);
}
else if (onlyDeals)
{
subQuery.Where(() => userReservationAlias.Id != null);
}
else
{
subQuery =
subQuery.Where(
() => reservationAlias.Id == null ||
reservationAlias.OperatorStatus == ReservationStatus.Accepted ||
reservationAlias.OperatorStatus == ReservationStatus.Pending);
}
}
var pageSubQuery = subQuery.Clone()
.Select(
Projections.ProjectionList().Add(
Projections.SqlGroupProjection("this_0_.Id as idAlias",
$"this_0_.Id, this_0_.StartDate, this_0_.DateCreated, this_0_.PricePerAdult, this_0_.EmptySeats, reservatio5_.NumberOfParticipants",
new string[] { "idAlias" }, new IType[] { NHibernate.NHibernateUtil.Int32 })));
pageSubQuery = SortSlotsQuery(pageSubQuery, () => reservationAlias, sortBy) as QueryOver<Slot, Slot>;
pageSubQuery.Skip(offset).Take(limit);
var queryOver = session.QueryOver(() => slotAlias)
.JoinAlias(() => slotAlias.Session, () => sessionAlias)
.JoinAlias(() => sessionAlias.Product, () => productAlias)
.JoinAlias(() => productAlias.Operator, () => operatorAlias)
.Left.JoinAlias(() => slotAlias.Reservation, () => reservationAlias)
.Left.JoinAlias(() => sessionAlias.GroupDiscounts, () => groupDiscountAlias);
queryOver = SortSlotsQuery(queryOver, () => reservationAlias, sortBy);
var result = queryOver.WithSubquery.WhereProperty(x => x.Id).In(pageSubQuery)
.TransformUsing(Transformers.DistinctRootEntity)
.Future();
var rowCount = subQuery.GetExecutableQueryOver(session).Select(Projections.CountDistinct<Slot>(x => x.Id)).FutureValue<int>();
return new PagenedResult<Slot>(rowCount.Value, offset, limit, result.ToArray());
代码的作用:获取插槽,过滤它们,然后创建分页子查询。然后使用分页子查询中的必要联接从数据库中提取插槽。这样我就可以通过一次数据库访问。