2009-04-27 27 views
8

Tôi cần phải sử dụng hàm year() và month() trong API tiêu chí để có thể thể hiện giới hạn bộ lọc doanh nghiệp. Các biểu thức nhưcách sử dụng hàm year() và month() trong API tiêu chí NH?

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

rõ ràng là không hoạt động - có giải pháp nào để đạt được điều này không?

Tôi biết điều đó hoàn toàn có thể trong HQL, nhưng tôi cần phải xây dựng các truy vấn sử dụng tiêu chuẩn API vì đang có một số quá trình thêm xử lý truy vấn thêm phân loại, phân trang vv ..


mẫu giải pháp HQL đó Tôi muốn viết lại API Tiêu chí:

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

Trả lời

8

Có thể đạt được điều này bằng cách sử dụng Projections.SQLFunction. giải pháp làm việc:

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

Điều gì đó có thể phù hợp với bạn?

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

Lưu ý rằng tôi đã thay đổi thứ tự biểu thức của bạn - Tôi giả định bạn đã đánh máy và bạn muốn truy vấn ngày giữa DateFrom và DateTo. Nếu ngày chứa dữ liệu thời gian, khái niệm thứ hai sẽ thay đổi để:

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

Đáp lại bình luận:

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

là đầu vào người dùng của bạn theo hình thức "YYMM"? Nếu đó là trường hợp, sau đó bạn chỉ phải phân tích ra năm và tháng từ chuỗi để tạo fromYear, fromMonth vv

Chỉnh sửa: 3 của tôi và cố gắng cuối cùng:

// 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

này không may là chưa đủ. Dữ liệu nhập của người dùng là năm + tháng và tôi cần trả về tất cả các đối tượng có Thời lượng giao cắt năm + tháng. Giải pháp Simmilar trong HQL trông giống như: var ym = year * 100 + month; var hql = ... (: ym giữa 100 * năm (f.Duration.DateFrom) + tháng (f.Duration.DateFrom) và 100 * year (f.Duration.DateTo) + month (f.Duration.DateTo) "; Tôi không thể tìm ra cách tạo cùng một truy vấn bằng API tiêu chí. – Buthrakaur

+0

để chỉnh sửa: Tôi chỉ kết hợp một năm + tháng. Câu chuyện của người dùng giống như:" hiển thị cho tôi đối tượng có thời lượng Tôi có thể có đối tượng {DateFrom = new DateTime (2008,1,1), DateTo = new DateTime (2222, 1, 2)} và đầu vào của người dùng là "tháng 9 năm 2009" - đề xuất của bạn không hoạt động ở đây . – Buthrakaur

0

Tôi không chắc tôi understod những gì bạn có ý nghĩa với câu hỏi của bạn nhưng tôi có một câu hỏi tương tự, và tôi giải quyết vấn đề với:

crit.Add(Expression.Sql("(YEAR({alias}.ObsDatum) = ?)", year, NHibernateUtil.String)) 
crit.Add(Expression.Sql("(MONTH({alias}.ObsDatum) = ?)", manad, NHibernateUtil.Int32)) 
Các vấn đề liên quan