NHibernate - Projection.Property по отдельным критериям с псевдонимом - PullRequest
2 голосов
/ 10 октября 2011

Я создаю полусложный отчетный запрос (возможно, это не лучший способ, но до этой проблемы он работал нормально).

// 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: Не удалось найти продажи недвижимости. Назначение Дата

Свойство определенно существует, если я удаляю псевдоним в Projection.Property (Projection.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 Ответ

1 голос
/ 31 октября 2011

Я думаю, что проблема может заключаться в том, что вы называете свой подзапрос как «Продажи», но вы уже определили псевдоним «продажи» в отдельных критериях. Sql определенно не чувствителен к регистру (и я не думаю, что псевдонимы NHibernate?)

В любом случае, я бы попытался изменить псевдоним в списке проекций, что-то вроде

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

Чтобы у вас не было двух потенциально конфликтующих псевдонимов.

...