You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在EF Core中提取DateTime小时并筛选非7-21点的数据?

问题描述

技术栈:

  • EFCore (7.0.5)
  • ASPNetCore (7.0.0)
  • Pomelo.EFCore.Mysql (7.0.0)

现有一段从表中获取数据的代码:

var v = await _dbContext.HistoLogs!
                 .Where(h => h.Datecre > DateTime.Today.AddDays(-31))
                 .ToListAsync();

这段代码可正常运行,但需要**排除7:00到21:00(早7点到晚9点)**的数据。

已能用MySQL语句实现该需求:

SELECT EXTRACT(HOUR FROM h.Datecre), h.Datecre, h.`Action` 
from myschema.HistoLogs h
WHERE Datecre > DATE_SUB(NOW(), INTERVAL 31 DAY)  AND 
(EXTRACT(HOUR FROM h.Datecre) BETWEEN 22 AND 23 OR EXTRACT(HOUR FROM h.Datecre) BETWEEN 0 AND 6)

但不清楚如何在EF Core中实现对应查询,尝试了以下代码但未生效,求正确写法:

var v = await _dbContext.HistoLogs!
                 .Where(h => h.Datecre > DateTime.Today.AddDays(-31))
                 .Where(h => h.Datecre.Hour < 7)
                 .Where(h => h.Datecre.Hour > 21)
                 .ToListAsync(); 

正确写法

你之前的代码问题在于连续使用两个Where,这要求数据同时满足Hour <7 并且 Hour>21——显然没有符合这个条件的时间,逻辑错误。

正确逻辑应该是或的关系,把两个条件合并到同一个Where中,用||连接:

var v = await _dbContext.HistoLogs!
                 .Where(h => h.Datecre > DateTime.Today.AddDays(-31) 
                             && (h.Datecre.Hour < 7 || h.Datecre.Hour > 21))
                 .ToListAsync();

Pomelo.EFCore.Mysql会自动将h.Datecre.Hour转换为MySQL的EXTRACT(HOUR FROM Datecre),最终生成的SQL和你手动编写的逻辑完全一致,能正确筛选出非7-21点的数据。

如果想和原生SQL里的DATE_SUB(NOW(), INTERVAL 31 DAY)完全对应(前者是数据库当前时间往前推31天,而DateTime.Today.AddDays(-31)是本地今天0点往前推31天),可以改用EF的数据库端时间函数:

var v = await _dbContext.HistoLogs!
                 .Where(h => h.Datecre > EF.Functions.Now().AddDays(-31) 
                             && (h.Datecre.Hour < 7 || h.Datecre.Hour > 21))
                 .ToListAsync();

内容的提问来源于stack exchange,提问作者Tanc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 04:10:07