#nhibernate #nhibernate-projections
#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>();
Это отлично работает и возвращает правильные результаты, однако теперь мне нужно ввести предложение 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»)), оно работает, однако оно выдает этот 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. Может помочь небольшая информация о лидах, промоутерах, назначении и продаже.
2. Запросы Crtieria устарели (почти)
Ответ №1:
Я думаю, проблема может заключаться в том, что вы присваиваете своему подзапросу псевдоним «Продажи», но вы уже определили псевдоним «продажи» в отдельных критериях. Sql, конечно, не чувствителен к регистру (и я не думаю, что псевдонимы NHibernate?)
В любом случае, я бы попробовал изменить псевдоним в списке проекций, что-то вроде
var projections = Projections.ProjectionList()
.Add(Projections.SubQuery(appts), "Appointments")
.Add(Projections.SubQuery(sales), "MySales");
Чтобы у вас не было двух потенциально конфликтующих псевдонимов.