EF Core 3.1 中的时间跨度问题

TimeSpan Issue in EF Core 3.1

我在使用 EF Core 3.1 查询 PostgreSQL 数据库时遇到问题。

查询很简单

var gamesQuery = this.dbContext.Games.Where(game => game.StartTime > DateTime.Now).AsQueryable();

// 'request.TimeFrom' is of type System.TimeSpan and the value is populated
gamesQuery = gamesQuery.Where(game => game.StartTime.TimeOfDay >= request.TimeFrom);

// .ToList()-int here causes the exception.
var games = gamesQuery.ToList();

异常消息明确指出无法翻译查询:

"The LINQ expression 'DbSet\r\n .Where(g => g.StartTime > DateTime.Now)\r\n .Where(g => g.StartTime.TimeOfDay >= __request_TimeFrom_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information."

问题是相同的查询在 .NET Core 2.2 中工作正常。 我还没有发现任何关于这个问题的信息。

有人知道这是什么原因还是我遗漏了什么?

目前 PostgreSQL EF Core 3.x 查询提供程序不支持翻译 DateTime.TimeOfDay - 请参阅 source code 中的 TODO 评论。

很可能是 "worked" 在 2.x 中默默地使用客户评估。但是隐式客户端评估 has been removed in 3.0 并且无法将其重新打开。

您可以尝试以下等效构造:

.Where(game => (game.StartTime - game.StartTime.Date) >= request.TimeFrom)

至少它不会产生上述异常。

如果它不起作用,请采纳他们的建议并通过在不可翻译表达式之前的适当位置插入 AsEnumerable() 明确切换到客户端评估。

我还没有尝试过,但一种解决方案可能是将 TimeOfDay 保存到 DateTime 旁边的数据库中 属性。然后你只需将它与你的 TimeSpan 变量进行比较。