2

我正在构建一个半复杂的报告查询(可能不是最好的方法,但在这个问题之前它可以正常工作)。

// total appointments
var appts = DetachedCriteria.For<Appointment>("appt")
    .CreateAlias("Lead", "lead")
    .CreateAlias("lead.Promoter", "leadPromoter", JoinType.LeftOuterJoin)
    .Add(Restrictions.EqProperty("leadPromoter.Id", "promoter.Id"))
    .SetProjection(Projections.ProjectionList()
                                   .Add(Projections.CountDistinct("appt.Id"));

// total sales
var sales = DetachedCriteria.For<Appointment>("sales")
    .CreateAlias("Lead", "lead")
    .CreateAlias("Sale", "sale")
    .CreateAlias("lead.Promoter", "leadPromoter", JoinType.LeftOuterJoin)
    .Add(Restrictions.EqProperty("leadPromoter.Id", "promoter.Id"))
    .SetProjection(Projections.ProjectionList()
                                   .Add(Projections.CountDistinct("sales.Id"));

var projections = Projections.ProjectionList()
    .Add(Projections.SubQuery(appts), "Appointments")
    .Add(Projections.SubQuery(sales), "Sales");


var reports = Session.CreateCriteria<Promoter>("promoter")
                .SetProjection(projections)
                .SetResultTransformer(Transformers.AliasToBean(typeof(PromoterReportDto)))
                .List<PromoterReportDto>();

这可以正常工作并带来正确的结果,但是现在我需要在每个预测的工作日为每个预测(num 约会、num 销售等)引入 where 子句。

为此,我将其添加到我的预测中:

// total appointments
var appts = DetachedCriteria.For<Appointment>("appt")
    .CreateAlias("Lead", "lead")
    .CreateAlias("lead.Promoter", "leadPromoter", JoinType.LeftOuterJoin)
    .Add(Restrictions.EqProperty("leadPromoter.Id", "promoter.Id"))
    .Add(Restrictions.Eq(
                        Projections.SqlFunction("day", NHibernateUtil.DateTime, Projections.Property("appt.AppointmentDate")), selectedDayOfWeek)
                    )
    .SetProjection(Projections.ProjectionList()
                                   .Add(Projections.CountDistinct("appt.Id"));

// total sales
var sales = DetachedCriteria.For<Appointment>("sales")
    .CreateAlias("Lead", "lead")
    .CreateAlias("Sale", "sale")
    .CreateAlias("lead.Promoter", "leadPromoter", JoinType.LeftOuterJoin)
    .Add(Restrictions.EqProperty("leadPromoter.Id", "promoter.Id"))
    .Add(Restrictions.Eq(
                        Projections.SqlFunction("day", NHibernateUtil.DateTime, Projections.Property("sales.AppointmentDate")), selectedDayOfWeek)
                    )
    .SetProjection(Projections.ProjectionList()
                                   .Add(Projections.CountDistinct("sales.Id"));

;

但是,它抱怨这个错误:

NHibernate.QueryException:找不到属性 sales.AppointmentDate

该属性确实存在,如果我删除 Projections.Property (Projections.Property("AppointmentDate")) 中的别名,它可以工作,但是它会产生以下 SQL:

       and datepart(day, this_0_.AppointmentDate) = 0 /* @p4 */
       and datepart(day, this_0_.AppointmentDate) = 0 /* @p5 */
       and datepart(day, this_0_.AppointmentDate) = 0 /* @p6 */
       and datepart(day, this_0_.AppointmentDate) = 0 /* @p7 */
       and datepart(day, this_0_.AppointmentDate) = 0 /* @p8 */
       and datepart(day, this_0_.AppointmentDate) = 0 /* @p9 */
       and datepart(day, this_0_.AppointmentDate) = 0 /* @p10 */) as y0_,

如您所见,它使用的是我的实体的第一个实例,而不是每个特定分离条件的实体。

很抱歉这个问题很长,我不太确定如何在没有所有代码等的情况下解释这个问题。

如果需要,我可以粘贴更多代码/SQL。

保罗

4

1 回答 1

1

我认为问题可能是您将子查询别名为“销售”,但您已经在分离条件中定义了别名“销售”。Sql 当然不区分大小写,(我不认为 N​​Hibernate 别名是?)

无论如何,我都会尝试更改投影列表中的别名,例如

var projections = Projections.ProjectionList()
   .Add(Projections.SubQuery(appts), "Appointments")
   .Add(Projections.SubQuery(sales), "MySales");

这样您就没有两个可能相互冲突的别名。

于 2011-10-31T05:40:50.340 回答