2017-05-19 97 views
2

QueryOver我有這個QueryOver方法:NHibernate的查詢/與日期時間比較

public IEnumerable<TrackedReportData> GetUnused(TimeSpan cacheExpiration) 
{ 
    return Session 
     .QueryOver<TrackedReportData>() 
     .Where(t => t.CacheSize > 0) 
     // TODO: NHibernate doesn't support DateTime comparison out-of-box. 
     //.Where(t => t.CacheSize > 0 && !t.IsRecentlyAccessed(cacheExpiration)) 
     .List() 
     .Where(t => !t.IsRecentlyAccessed(cacheExpiration)); 
} 

目前,我過濾SQL外部的我的收藏。表現不佳。

IsRecentlyAccessed方法是這樣的:

/// <summary> 
/// Returns true if the cacheMeta has been accessed within the last `cacheExpiration` 
/// number of milliseconds. 
/// </summary> 
public bool IsRecentlyAccessed(TimeSpan cacheExpiration) 
{ 
    if (!LastAccessDate.HasValue) 
     return false; 

    return DateTime.Now.Subtract(LastAccessDate.Value) <= cacheExpiration; 
} 

NHibernate的不支持DateTime.Subtract也不處理DateTime1 - DateTime2很容易。

我已經瀏覽了網上的資源,似乎每個人都建議過於複雜的function expressionsextension methods。當我有興趣做的是減去一個值時,這些解決方案看起來有點過分。

有沒有簡單的解決方案?製作SQL查詢的手動方法似乎是最好的選擇,但這是一種恥辱,NHibernate在其軌跡上被阻止了 ,這似乎是微不足道的。

+0

你試過加-1嗎? – jdweng

回答

1

怎麼樣以下?

public IEnumerable<TrackedReportData> GetUnused(TimeSpan cacheExpiration) 
{ 
    return Session 
     .QueryOver<TrackedReportData>() 
     .Where(t => t.CacheSize > 0) 
     .Where(Restrictions.Or(
      Restrictions.On<TrackedReportData>(t => t.LastAccessDate).IsNull, 
      Restrictions.Where<TrackedReportData>(
       t => t.LastAccessDate < DateTime.Now.Add(-cacheExpiration)))) 
     .List(); 
} 

NHibernate知道如何比較日期。這是你的情況不支持的日期計算。將它移動到參數上會導致它在運行時進行評估,而不是試圖將其轉換爲SQL。

如果要將日期計算轉換爲SQL,請參閱此answer to another question

0

的語法不是很大,這將需要一些調整,但是你應該能夠做這樣的事......

return Session 
    .QueryOver<TrackedReportData>() 
    .Where(t => t.CacheSize > 0) 
    .Where(
     Restrictions.Lte(
      Projections.SqlFunction(
       new VarArgsSQLFunction("(", "-", ")"), 
       NHibernateUtil.DateTime, 
       Projections.Property(t => t.LastAccessDate), 
       Projections.Constant(DateTime.Now)), 
      cacheExpiration);