NHibernate - Projections.Property与Alias的分离标准

时间:2011-10-10 15:41:02

标签: nhibernate nhibernate-projections

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

// 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。

1 个答案:

答案 0 :(得分:1)

我认为问题可能是您将子查询别名为“Sales”,但您已经在分离的条件中定义了别名“sales”。 Sql肯定不区分大小写(我不认为NHibernate别名是?)

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

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

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