2012-06-06 28 views
6

Tôi muốn tìm nạp tất cả các bản ghi từ ngày cụ thể, bất kể thời gian nào được liên kết với những bản ghi đó. Cho đến nay tôi có phương pháp như thế này:Tìm nạp bản ghi theo ngày chỉ với so sánh từng phần bằng cách sử dụng nhibernate

public IQueryable<Record> QueryByDay(DateTime day) 
{ 
    DateTime from = day.Date; 
    DateTime to = day.Date.AddDays(1); 

    return repository.Table 
     .Where(t => t.MyDate >= from && t.MyDate < to); 
    } 

Nhưng trong LINQ-to-đối tượng chúng ta có thể làm (giả sử bảng tại là một số bộ sưu tập):

public IEnumerable<Record> QueryByDay(DateTime day) 
{ 
    return repository.Table 
     .Where(t => t.MyDate.Date == day.Date); 
} 

Mà rõ ràng là dễ đọc hơn và cảm thấy sạch sẽ hơn . Tôi đã tự hỏi nếu có cách nào tốt hơn để viết phương pháp đầu tiên bằng cách sử dụng lưu trữ cơ sở dữ liệu và nhibernate?

+0

Tôi tin rằng biểu mẫu bạn sử dụng cho L2O hoạt động tốt với NH. –

+0

@Diego Mijelshon Bạn có thể cho tôi biết verison NHibernate nào bạn đang sử dụng mà nó hoạt động không? Tại dự án tôi đang làm việc tại chúng tôi đang sử dụng v. 2.1 và điều này là ném NHibernate.QueryException. – 0lukasz0

+1

2.1 là 3 tuổi và không được hỗ trợ. 3.3 là bản phát hành ổn định hiện tại. –

Trả lời

6

Như đã nói trong các ý kiến, truy vấn LINQ của bạn hoạt động tốt với NH 3.3.

Trong phiên bản trước đó, bạn có thể sử dụng HQL:

return session.CreateQuery("from MyClass where date(MyDate) = :day") 
       .SetParameter("day", day.Date) 
       .List<MyClass>(); //executes 

Bạn cũng có thể sử dụng chức năng date từ Tiêu chuẩn, thông qua SqlFunction. Điều này phức tạp hơn, nhưng cho phép tạo nhiều truy vấn động hơn:

return session.CreateCriteria<Foo>() 
       .Add(Restrictions.Eq(
         Projections.SqlFunction("date", 
               NHibernateUtil.Date, 
               Projections.Property("MyDate")), 
         day.Date)) 
       .List<MyClass>(); //executes 
2
public IEnumerable<Record> QueryByDay(DateTime day) 
{ 
    return repository.Table 
     .Where(t => t.MyDate.Day == day.Day && t.MyDate.Month == day.Month && t.MyDate.Year == day.Year); 
} 
+0

Bạn có thể cho tôi biết verison NHibernate nào bạn đang sử dụng mà nó hoạt động không? Tại dự án tôi đang làm việc tại chúng tôi đang sử dụng v. 2.1 và điều này là ném NHibernate.QueryException. – 0lukasz0

+1

Ồ! v2.1 không hỗ trợ LINQ nhưng có một chi nhánh với nhà cung cấp LINQ, một nhà cung cấp không hoạt động. Phiên bản 3+ bao gồm nhà cung cấp Linq gốc. Như @Diego Mihelshon chỉ ra, "2.1 là 3 tuổi và không được hỗ trợ. 3.3 là bản phát hành ổn định hiện tại". – ivowiblo

+0

Ok, tôi cung cấp cho +1 này mặc dù nếu SomeDateAttr.Date == OtherDate.Date hoạt động trong NH 3+ sau đó nó là cách tiếp cận tốt hơn trong quan điểm của tôi. – 0lukasz0

2

Tùy thuộc vào nhà cung cấp LINQ. Tôi không chắc chắn nếu NHibernate LINQ nhà cung cấp hỗ trợ cú pháp item.SomeDateProperty.Date == x và tôi nghi ngờ nó. Tuy nhiên, bạn có thể làm cho phương pháp mở rộng của riêng bạn như vậy:

public static IQueryable<T> FilterByDate(this IQueryable<T> This, Expression<Func<T, DateTime>> getProperty, DateTime date) 
{ 
    DateTime from = day.Date; 
    DateTime to = day.Date.AddDays(1); 
    return This.Where(x=> 
    Expression.And(
     Expression.GreaterThan(getProperty, Expression.Variable(from)), 
     Expression.LessThan(getProperty, Expression.Variable(to))); 

} 

Điều này sẽ không xây dựng cách thức hiện tại - Tôi chỉ cố gắng cung cấp cho bạn ý tưởng về việc cần làm.

Sau đó bạn có thể sử dụng nó như vậy:

var result = repository.Table.FilterByDate(x=>x.MyDate, new DateTime(2012, 6,6)); 
+0

+1, tôi thích ý tưởng, mặc dù trông giống như nhiều hơn đến nay NHibernate hỗ trợ các giải pháp dễ nhất. – 0lukasz0

Các vấn đề liên quan