2009-04-27 38 views
8

我需要在Criteria API中使用year()和month()函数来表达业务过滤器约束。像如何在NH Criteria API中使用year()和month()函数?

cri.Add(Expression.Ge("year(Duration.DateFrom)", Year.Value)); 
cri.Add(Expression.Le("year(Duration.DateTo)", Year.Value)); 

明显表达式不工作 - 没有任何解决方案是如何实现这一目标?

我知道这是完全有可能的HQL,但我需要使用标准的API来构建查询,但由于是一些附加的工艺处理查询添加排序,分页等。


样品HQL解决方案我想重写Criteria API:

var ym = year * 100 + month; 
var hql = ...(:ym between 100 * year(f.Duration.DateFrom) + month(f.Duration.DateFrom) and 100 * year(f.Duration.DateTo) + month(f.Duration.DateTo)"; 

回答

8

这有可能实现这一目标使用Projections.SQLFunction。工作液:

ISQLFunction sqlAdd = new VarArgsSQLFunction("(", "+", ")"); 
ISQLFunction sqlMultiply = new VarArgsSQLFunction("(", "*", ")"); 

var ym = Year.Value * 100 + Month.Value; 
var dateFromMonthProj = Projections.SqlFunction("month", NHibernateUtil.Int32, Projections.Property("PurchaseDuration.DateFrom")); 
var dateFromYearProj = Projections.SqlFunction("year", NHibernateUtil.Int32, Projections.Property("PurchaseDuration.DateFrom")); 
var dateToMonthProj = Projections.SqlFunction("month", NHibernateUtil.Int32, Projections.Property("PurchaseDuration.DateTo")); 
var dateToYearProj = Projections.SqlFunction("year", NHibernateUtil.Int32, Projections.Property("PurchaseDuration.DateTo")); 
var calculatedYMFrom = Projections.SqlFunction(sqlAdd, NHibernateUtil.Int32, Projections.SqlFunction(sqlMultiply, NHibernateUtil.Int32, dateFromYearProj, Projections.Constant(100)), dateFromMonthProj); 
var calculatedYMTo = Projections.SqlFunction(sqlAdd, NHibernateUtil.Int32, Projections.SqlFunction(sqlMultiply, NHibernateUtil.Int32, dateToYearProj, Projections.Constant(100)), dateToMonthProj); 
cri.Add(Restrictions.Le(calculatedYMFrom, ym)); 
cri.Add(Restrictions.Ge(calculatedYMTo, ym)); 
1

会是这样的工作吗?

cri.Add(Expression.Ge("Duration.DateFrom", new Date(fromYear, 1, 1)); 
cri.Add(Expression.Le("Duration.DateTo", new Date(toYear, 12, 31)); 

请注意,我改变了你的表达顺序 - 我假设你犯了一个错字,你想查询DateFrom和DateTo之间的日期。如果日期包含时间数据,第二个表达式将变为:

cri.Add(Expression.Lt("Duration.DateTo", new Date(toYear + 1, 1, 1)); 

在回应评论:

cri.Add(Expression.Ge("Duration.DateFrom", new Date(fromYear, fromMonth, 1)); 
// Actual code needs to get last day of to month since it will not always be 31 
cri.Add(Expression.Le("Duration.DateTo", new Date(toYear, toMonth, 31)); 

的形式是“YYMM”你的用户输入?如果是这样的话,那么你就必须从字符串解析出的年份和月份创建fromYear,fromMonth等

编辑:我的第三和最后的努力:

// First parse the input, e.g: september 2009 into 9 (inMonth) and 2009 (inYear) 
var fromDate = new DateTime(inYear, inMonth, 1); 
var toDate = fromDate.AddMonths(1).AddDays(-1); 

cri.Add(Expression.Ge("Duration.DateFrom", fromDate)); 
cri.Add(Expression.Le("Duration.DateTo", toDate)); 
+0

这不幸是不够的。用户输入是年份+月份,我需要返回持续时间与年份+月份相交的所有对象。 HQL中的Simmilar解决方案如下所示: var ym = year * 100 + month; var hql = ...(:ym在100 *年(f.Duration.DateFrom)+月份(f.Duration.DateFrom)和100 *年份(f.Duration.DateTo)+月份(f.Duration.DateTo) “; 我无法弄清楚如何使用Criteria API创建相同的查询 – Buthrakaur 2009-04-27 14:04:50

0

我不知道我understod你的意思你的问题,但我也有类似的问题,我解决了这个问题:

crit.Add(Expression.Sql("(YEAR({alias}.ObsDatum) = ?)", year, NHibernateUtil.String)) 
crit.Add(Expression.Sql("(MONTH({alias}.ObsDatum) = ?)", manad, NHibernateUtil.Int32)) 
相关问题