我有这个QueryOver方法:
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 expressions或extension methods。当我感兴趣的是减去一个值时,这些解决方案似乎有些过分。
有没有简单的解决方案?制作SQL查询的手动方法似乎是最好的选择,但令人遗憾的是NHibernate已经停止了 这似乎是微不足道的。
答案 0 :(得分:2)
以下情况如何?
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。
答案 1 :(得分: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);