实现它的一种方法是:
val now = DateTime.now
val today = now.toLocalDate
val tomorrow = today.plusDays(1)
val startOfToday = today.toDateTimeAtStartOfDay(now.getZone)
val startOfTomorrow = tomorrow.toDateTimeAtStartOfDay(now.getZone)
val todayLogItems = logItems.filter(logItem =>
logItem.MyDateTime >= startOfToday && logItem.MyDateTime < startOfTomorrow
).list
有没有办法以更简洁的方式编写查询?有点像:
logItems.filter(_.MyDateTime.toDate == DateTime.now.toDate).list
我问这个是因为LINQ to NHibernate是可以实现的(Fetching records by date with only day part comparison using nhibernate)。
答案 0 :(得分:4)
除非Slick joda映射器增加了对比较的支持,否则你运气不好,除非你自己添加它。为了给它一个镜头,这些可能是有用的指针: * http://slick.typesafe.com/doc/2.0.0/userdefined.html * http://slick.typesafe.com/doc/2.0.0/api/#scala.slick.lifted.ExtensionMethods * https://github.com/slick/slick/blob/2.0.0/src/main/scala/scala/slick/lifted/ExtensionMethods.scala
我创建了一张票,可以在Slick中查看它:https://github.com/slick/slick/issues/627
答案 1 :(得分:2)
通过使用LocalDateTimes而不是直接使用LocalDates,您会感到困惑:
val today = LocalDate.now
val todayLogItems = logItems.filter(_.MyDateTime.toLocalDate isEqual today)
<强>更新强>
这里的问题需要 Major 澄清,Slick只是通过标签顺便提及。
然而...... Slick是这个问题的核心,这取决于filter
操作实际上是通过PlainColumnExtensionMethods
我对这个库并不是很熟悉,但这肯定意味着你只能被限制在可以在SQL中执行的操作。因为这是一个Column [DateTime],所以你必须将它与另一个DateTime进行比较。
至于LINQ示例,它似乎建议首先获取所有内容然后按照上面的示例继续进行(在Scala中执行比较而不是在SQL中执行比较)。这是一个选项,但我怀疑你不会想要它所带来的性能成本。
更新2 (只是为了澄清)
没有答案。
无法保证您的基础数据库能够在日期和时间戳之间进行相等性检查,因此不能依赖现有的这种能力。
你被困在一块岩石和一块坚硬的地方之间。您可以像现在一样在时间戳之间进行范围检查,也可以从查询中提取所有内容并在Scala中对其进行过滤 - 这可能会带来很高的性能成本。
最终更新
要参考您引用的Linq / NHibernate问题,以下是一些引用:
所以答案似乎是:
最好的情况是NHibernate可以将日期/时间戳比较转换为时间戳范围检查。做这样的事情是关于Slick(和slick-joda-mapper)如何处理比较的一个非常深刻的问题,你在过滤器中使用它的事实是偶然的。
您需要一个极其引人注目的用例来自行编写这样的功能,因为存在创建复杂错误的风险。你会好起来的:
如果是助手:
def equalsDate(dt: LocalDate) = {
val start = dt.toDateTimeAtStartOfDay()
val end = dt.plusDays(1).toDateTimeAtStartOfDay()
(col: Column[DateTime]) => {
col >= start && col < end
}
}
val isToday = equalsDate(LocalDate.now)
val todayLogItems = logItems.filter(x => isToday(x.MyDateTime))