NHibernate — проекции.Свойство для отдельных критериев с псевдонимом

#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");
  

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