【发布时间】:2015-03-23 22:31:08
【问题描述】:
这里有一个很好的问答来解决这个问题: NHibernate COALESCE issue
我需要能够将日期对象与内部联接中的日期值进行比较。这里不熟悉的领域是这个 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 时,我可以用这个 restriction 对象替换 Where 子句之一
var foo = CurrentSession().QueryOver<Site>(() => sa)
.Inner.JoinQueryOver<ProfitCenter>(() => pca)
.Where(restriction)
最终答案
这需要引入一个新的“扁平化”域“ResultModel”(SiteWithWindowsTimezoneId),以便我可以从查询中返回更具体的模型,并避免延迟加载当前与 Site 关联的所有其他内容。这种新的查询样式已将 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
【问题讨论】:
标签: c# nhibernate queryover nhibernate-criteria