Nhibernate 如何在NH标准API中使用year()和month()函数?

Nhibernate 如何在NH标准API中使用year()和month()函数?,nhibernate,criteria,Nhibernate,Criteria,我需要在Criteria API中使用year()和month()函数来表示业务筛选器约束。表达方式如 cri.Add(Expression.Ge("year(Duration.DateFrom)", Year.Value)); cri.Add(Expression.Le("year(Duration.DateTo)", Year.Value)); 显然不起作用-有没有任何解决方案来实现这一点 我知道这在HQL中是完全可能的,但我需要使用CriteriaAPI构造查询,因为有一些额外的进程处理

我需要在Criteria API中使用year()和month()函数来表示业务筛选器约束。表达方式如

cri.Add(Expression.Ge("year(Duration.DateFrom)", Year.Value));
cri.Add(Expression.Le("year(Duration.DateTo)", Year.Value));
显然不起作用-有没有任何解决方案来实现这一点

我知道这在HQL中是完全可能的,但我需要使用CriteriaAPI构造查询,因为有一些额外的进程处理查询,包括排序、分页等


我想将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)";

你喜欢这个工作吗

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

使用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));

我不确定我是否理解你的问题的意思,但我有一个类似的问题,我用以下方法解决了这个问题:

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

不幸的是,这还不够。用户输入是年+月,我需要返回所有持续时间与年+月相交的对象。HQL中的模拟解决方案如下所示:var ym=年*100+月;var hql=…(:ym介于100*年(f.Duration.DateFrom)+月(f.Duration.DateFrom)和100*年(f.Duration.DateTo)+月(f.Duration.DateTo)”之间;我无法理解如何使用条件API创建相同的查询。为了响应编辑:我只有一年+月的组合。用户故事如下:向我显示持续时间覆盖2009年9月的对象”。我可以使用对象{DateFrom=new DateTime(2008,1,1),DateTo=new DateTime(2222,1,2)},用户输入为“2009年9月”-您的建议在这里不起作用。