2009-04-27 79 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)) 
相關問題