【问题标题】:How to Use Dates in Where Clause in EF Core?如何在 EF Core 的 Where 子句中使用日期?
【发布时间】:2020-01-06 18:03:06
【问题描述】:

我需要按日期过滤我的查询,但在这种情况下我不关心存储在 SQL 数据库中的时间部分。

我第一次尝试类似

var now = DateTime.Now.Date;
Where(x => x.CreatedDate.Date.Compare(now) == 0)

但这似乎都得到了本地检查,使查询变慢。如果不让它在本地进行检查,我怎么能做到这一点?

我非常想找出今天(2020-01-06)发生的所有结果。

【问题讨论】:

  • 为什么不简单地使用这个?:Where(x => x.CreatedDate.Date == now) 它应该在服务器上执行
  • 我认为仍然会在本地翻译,
  • 没有。在服务器上。刚刚检查了WHERE(CreatedDate.Date == now) 转换为WHERE ((CONVERT(date, [x].[CreatedDate]) = '2019-01-01T00:00:00.000')
  • 奇怪,让我再试一次,因为在我的日志中它说它将在本地转换。

标签: c# sql datetime ef-core-2.2


【解决方案1】:

在构建 Lambda/Linq 表达式时,可用于可翻译类型的方法数量有限。这是因为每个方法都需要额外的代码,以便可以将其转换为 sql 存储表达式。这意味着您必须检查是否支持您想要使用并期望被转换为 sql 存储表达式的任何方法。

在这种情况下,DateTime.Compare 不受支持。

这里最简单的做法是进行简单的范围比较,因为时间包含在您的持久值中。

var start = DateTime.Now.Date;
var end = start.AddDays(1);

Where(x => x.CreatedDate >= start && x.CreatedDate < end)

这将导致sargable 查询。

【讨论】:

  • 是的,.Date 似乎不受支持,如何在不先编写代码并等待查看错误日志的情况下检查它们是否有效。
  • 刚刚检查过 DateTime.Date。已验证 WHERE(CreatedDate.Date == now) 转换为 WHERE ((CONVERT(date, [x].[CreatedDate]) = '2019-01-01T00:00:00.000')
  • 刚刚检查了一个表,该表有 20 万条记录,该记录按该日期时间字段进行索引。无论有没有转换,估计的执行都没有差异。 SQL Server 是相当聪明的新星时代......
  • @tgralex - 就是这样。
【解决方案2】:

使用

var now = DateTime.Now.Date
...WHERE(CreatedDate.Date == now)

我刚刚检查了上面是否转换为以下 SQL 查询:

WHERE ((CONVERT(date, [x].[CreatedDate]) = '2019-01-07T00:00:00.000')

我使用这个 (link) 方法来查看 LINQ 转换成什么

【讨论】:

    猜你喜欢
    • 2022-06-22
    • 1970-01-01
    • 2022-07-13
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多