2015-03-23 2 views
1

Существует большая Q/A, чтобы предварить этот вопрос здесь: NHibernate COALESCE issueNHibernate сравнение ограничения на слившуюся дату

Мне нужно, чтобы иметь возможность сравнивать объект даты в значение даты внутри внутреннего соединение. Незнакомая территория здесь была реализация этого COALESCE вместе с датой LT ограничения

Вот мой текущий запрос SQL

SELECT DISTINCT Sites.* 
FROM Sites 
INNER JOIN Sites_WF_Info 
     ON Site_Key = SiteWFInfo_Site_Key 
     AND SiteWFInfo_Effective_Date <= @today 
     AND @today <= SiteWFInfo_End_Date 
INNER JOIN Profit_Centers 
     ON Site_Key = ProfCtr_Site_Key 
     AND ProfCtr_Open_Date <= @today 
     AND @today < Coalesce(ProfCtr_Close_Date, '6/6/2079') 

То, что я хотел бы знать, как идти об использовании постоянной в месте свойства ExpenseReport.PeriodFrom ==> left.

В идеале, я хотел бы установить левый/правый

// DateTime effDate is passed in 
var left = Projections.Property<DateTime>(effDate); 
var right = Projects.SqlFunction("COALESCE", 
      NHibernateUtil.DateTime, 
      Projections.Constant(DateTime.Parse("6/6/2079").Date, NHibernateUtil.DateTime), 
      Projections.Property<ProfitCenter>(pc => pc.CloseDate)); 

Тогда, когда ограничение вызывается

var restriction = Restrictions.LtProperty(left, right); 

Так что, когда я строю QueryOver <> Я могу заменить этот ограничение объект для одного из пунктов, где содержатся статьи

var foo = CurrentSession().QueryOver<Site>(() => sa) 
    .Inner.JoinQueryOver<ProfitCenter>(() => pca) 
    .Where(restriction) 

ПОСЛЕДНИЙ ОТВЕТ

Это потребовало введения новой «сплющенные» домен «ResultModel» (SiteWithWindowsTimezoneId), так что я мог бы вернуть более конкретную модель из моего запроса и избежать ленивые загрузки всех остальных которые в настоящее время связаны с сайтом. Этот новый стиль запроса превратил метод запросов 16 + sql в один запрос. Экономия стоила времени. В очередной раз благодарим за помощь. Надеюсь, что этот смысл полезен кому-то в будущем.

SiteWorkforceInfo swia = null; 
SiteWorkforceConfig swcfg = null; 
ProfitCenter pca = null; 
Site sa = null; 
SiteWithWindowsTimezoneId siteResult = null; 

var leftProfCloseDate = Projections.Constant(effectiveDate); 
var rightProfCloseDate = Projections.SqlFunction("COALESCE", 
    NHibernateUtil.DateTime, 
    Projections.Property<ProfitCenter>(pc => pc.CloseDate), 
    Projections.Constant(DateTime.Parse("6/6/2079").Date, NHibernateUtil.DateTime) 
); 

var profCloseDateRestriction = Restrictions.LtProperty(leftProfCloseDate, rightProfCloseDate); 

var activeSites = CurrentSession().QueryOver<SiteWorkforceInfo>(() => swia) 
    .Inner.JoinQueryOver<Site>(() => swia.Site,() => sa) 
    .Left.JoinQueryOver<SiteWorkforceConfig>(() => sa.SiteWFConfig,() => swcfg) 
    .Inner.JoinQueryOver<ProfitCenter>(() => sa.ProfitCenters,() => pca) 
    .Where(() => swia.EffectiveDate <= effectiveDate) 
    .Where(() => effectiveDate <= swia.EndDate) 
    .Where(() => pca.OpenDate <= effectiveDate) 
    .Where(profCloseDateRestriction) 
    .Where(() => swia.TimeCaptureRule > 0) 
    .SelectList(
     list => list 
      .Select(() => sa.Key).WithAlias(() => siteResult.Key) 
      .Select(() => sa.Id).WithAlias(() => siteResult.Id) 
      .Select(() => sa.IdFormatted).WithAlias(() => siteResult.IdFormatted) 
      .Select(() => sa.Description).WithAlias(() => siteResult.Description) 
      .Select(() => swcfg.WindowsTimezoneId).WithAlias(() => siteResult.WindowsTimezoneId) 
       ) 
    .TransformUsing(Transformers.AliasToBean<SiteWithWindowsTimezoneId>()) 
    .List<SiteWithWindowsTimezoneId>(); 

return activeSites; 

--- Результирующий запрос ---

SELECT sa1_.Site_Key as y0_, 
    sa1_.Site_Id as y1_, 
    sa1_.Site_Id_Formatted as y2_, 
    sa1_.Site_Description as y3_, 
    swcfg2_.SiteWFCfg_Windows_Timezone_Id as y4_ 
FROM Sites_WF_Info this_ 
inner join Sites sa1_ 
    on this_.SiteWFInfo_Site_Key=sa1_.Site_Key 
inner join Profit_Centers pca3_ 
    on sa1_.Site_Key=pca3_.ProfCtr_Site_Key 
left outer join Sites_WF_Configuration swcfg2_ 
    on sa1_.Site_Key=swcfg2_.SiteWFCfg_Site_Key 
WHERE this_.SiteWFInfo_Effective_Date <= @p0 
    and @p1 <= this_.SiteWFInfo_End_Date 
    and pca3_.ProfCtr_Open_Date <= @p2 
    and @p3 < coalesce(pca3_.ProfCtr_Close_Date, @p4) 
    and this_.SiteWFInfo_TimeCapRule_Key > @p5 

ответ

2

Если я правильно понял, мы должны заменить left(в настоящее время проекции собственности) с effDate постоянной проекцией. Тогда мы можем сделать это как этот

// instead of this 
// var left = Projections.Property<DateTime>(effDate); 

// we would use this 
// DateTime effDate is passed in 
var effDate = DateTime.Today.Date; // C#'s today 
var left = Projections.Constant(effDate); 

А также, мы должны перейти (изменение порядка) нашего «COALESCE», потому что имущество должно идти первым: Coalesce (ProfCtr_Close_Date, «6/6/2079 ')

var right = Projects.SqlFunction("COALESCE", 
    NHibernateUtil.DateTime, 

    // As DOC of COALESCE says: 
    // "Evaluates the arguments in order and returns the current value of 
    // the first expression that initially does not evaluate to NULL." 

    Projections.Property<ProfitCenter>(pc => pc.CloseDate), 
    Projections.Constant(DateTime.Parse("6/6/2079").DateNHibernateUtil.DateTime) 
    ); 

Наконец, мы должны использовать тот же псевдоним для соединенных столбцов. Давайте настроить основной запрос немного:

var foo = CurrentSession().QueryOver<Site>(() => sa) 
    .Inner.JoinQueryOver<ProfitCenter>(() => sa.ProfitCenter,() => pca) 
    .Where(restriction) 

И правая сторона должна использовать pca а

var right = Projects.SqlFunction("COALESCE", 
    NHibernateUtil.DateTime, 
    // be sure that column goes to correct table 
    // ==> use the same alias 
    Projections.Property(() => pca.CloseDate), 
    Projections.Constant(DateTime.Parse("6/6/2079").DateNHibernateUtil.DateTime) 
    ); 
+0

Projections.Constant! Спасибо. Я обновил свой SQL-запрос выше, чтобы теперь включить таблицу SiteWorkforceInfo. Это немного мало, потому что модель сайта домена не ссылается на SiteWorkforceInfo (ов) таким же образом, что и ссылки на центры прибыли.В настоящее время я пытаюсь построить запрос, начиная с объекта SiteWorkforceInfo. – beauXjames

+0

В случае, если 'SiteWorkforceInfo' не ссылается на домен сайта ... это вряд ли сработает. Причина в том, что NHibernate может делать JOIN ** только **, связанные с настройками в сопоставлении. Другими словами, мы не можем создать никакой другой JOIN, кроме тех, которые исходят из отношений * (много-к-одному, один-ко-многим) *, определенных в нашем отображении. Но действительно ли будет проблемой просто расширить модель? и создать такую ​​ссылку? –

+0

, работающий над этим ... «босс» предпочитает не вводить дополнительные «temp» модели в Core ... это становится длиннее;) – beauXjames

Смежные вопросы