使用 LocalDateTimes 而不是直接使用 LocalDates 会造成混淆:
val today = LocalDate.now
val todayLogItems = logItems.filter(_.MyDateTime.toLocalDate isEqual today)
更新
这里的问题需要主要澄清一下,Slick 只是顺便提及,通过标签。
但是... Slick 是这个问题的核心,这取决于 filter 操作实际上是通过 PlainColumnExtensionMethods 进入 SQL 查询的事实
我对这个库并不太熟悉,但这肯定意味着您仅限于可以在 SQL 中执行的操作。由于这是一个 Column[DateTime],因此您必须将其与另一个 DateTime 进行比较。
对于 LINQ 示例,似乎建议首先获取所有内容,然后按照我上面的示例继续(在 Scala 中而不是在 SQL 中执行比较)。这是一个选项,但我怀疑您不会想要它所带来的性能成本。
更新 2(只是为了澄清)
没有答案。
无法保证您的底层数据库能够在日期和时间戳之间进行相等性检查,因此 slick 不能依赖现有的这种能力。
你被困在一块石头和一个坚硬的地方之间。要么像你一样在时间戳之间进行范围检查,要么从查询中提取所有内容并在 Scala 中对其进行过滤——这可能会带来沉重的性能成本。
最终更新
要参考您引用的 Linq/NHibernate 问题,这里有几个引号:
- 您还可以通过 SqlFunction 使用 Criteria 中的日期函数
- 这取决于 LINQ 提供程序
- 我不确定 NHibernate LINQ 提供程序是否支持...
所以答案似乎是:
- 依靠 NHibernate 将日期强制逻辑推送到数据库中,如果这是不可能的,可能会默默地削弱性能(通过获取所有记录并在本地过滤)
- 靠你写自定义SQL逻辑
最好的情况是 NHibernate 可以将日期/时间戳比较转换为时间戳范围检查。做这样的事情是一个关于 Slick(和 slick-joda-mapper)如何处理比较的非常深刻的问题,您在过滤器中使用它的事实是偶然的。
考虑到创建复杂错误的风险,您需要非常引人注目的用例来自己编写这样的功能。你会过得更好:
- 将列拆分为单独的日期/时间列
- 将日期添加为计算列(可能在视图中)
- 使用自定义 SQL(或存储过程)进行查询
- 坚持范围检查
- 使用辅助函数
在助手的情况下:
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))