NHibernate - Projections.Property 基于具有 Alias 的分离标准
我正在构建一个半复杂的报告查询(可能不是最好的方法,但在这个问题之前它工作得很好)。
// 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>();
这工作正常并返回正确的结果,但是现在我需要在每个预测的工作日对每个预测(预约数、销售数等)引入一个 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:找不到房产销售.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。
保罗
I am building a semi-complex report query (may not be the best way, but it works fine up until this issue).
// 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>();
This works fine and brings back correct results, however now I need to introduce a where clause on each of the projections (num appointments, num sales etc) on the week day of each projection.
To do this I was adding this to my 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"))
.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"));
;
However, it is complaining with this error:
NHibernate.QueryException: Could not find property sales.AppointmentDate
The property definetly exists, if i remove the alias in the Projections.Property (Projections.Property("AppointmentDate")), it works, however it produces this 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_,
As you can see it's using the first instance of my entity, rather than the entity for each specific detached criteria.
Sorry for the long question, i'm not quite sure how to explain the issue without all the code etc.
I can paste up some more code / SQL if needed.
Paul
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为问题可能是您将子查询别名为“Sales”,但您已经在分离条件中定义了别名“sales”。 Sql 当然不区分大小写,(我不认为 NHibernate 别名是区分大小写的?)
在任何情况下,我都会尝试更改投影列表中的别名,例如,
这样您就不会有两个可能冲突的别名。
I think the problem may be that you are aliasing your subquery as "Sales" but you already defined the alias "sales" in the detached criteria. Sql certainly isn't case-sensitive, (and I don't think NHibernate aliases are?)
In any case, I would try changing the alias in the projection list, something like
So that you don't have two potentially conflicting aliases.