简体   繁体   English

在MySQL和Entity Framework 6的Where中使用TimeSpan时出现错误的结果

[英]Bad results when using TimeSpan in Where with MySQL and Entity Framework 6

We have table "Tasks": 我们有表“任务”:

Id | ToTime
1  | 23:59:59

And code: 和代码:

TimeSpan currentTime = DateTime.Now.TimeOfDay;
var count = context.Tasks.Where(p => p.ToTime > currentTime).Count();

The problem: 问题:

Theoretically, count should be always equals to 1 (in a daytime). 从理论上讲, count应该总是等于1(白天)。 But that not so cause sometimes (in random time) MySQL finds no rows (count = 0). 但事实并非如此(在随机时间内)MySQL没有找到任何行(count = 0)。

Why? 为什么?

Take a look at answer. 看看答案。 It took 5 hours to find solution. 花了5个小时才找到解决方案。

Milliseconds 毫秒

Entity Framework generate SQL like this: 实体框架生成如下SQL:

SELECT
`GroupBy1`.`A1` AS `C1`
FROM (SELECT
COUNT(1) AS `A1`
FROM `Tasks` AS `Extent1`
 WHERE `Extent1`.`ToTime` > '0 04:24:49.1438543') AS `GroupBy1`

But MySQL allowing only 6 digits for milliseconds. 但MySQL只允许6位数毫秒。 From MySQL docs : 来自MySQL文档

A trailing fractional seconds part is recognized in the 'D HH:MM:SS.fraction', 'HH:MM:SS.fraction', 'HHMMSS.fraction', and HHMMSS.fraction time formats, where fraction is the fractional part in up to microseconds (6 digits) precision. 在'D HH:MM:SS.fraction','HH:MM:SS.fraction','HHMMSS.fraction'和HHMMSS.fraction时间格式中识别尾随小数秒部分,其中分数是小数部分高达微秒(6位)的精度。 Although this fractional part is recognized, it is discarded from values stored into TIME columns. 尽管识别了该小数部分,但它将从存储在TIME列中的值中丢弃。

Extra digits appears because of redundancy TimeSpan and EntityFramework do not cuts that extra digits. 由于冗余而出现额外数字TimeSpan和EntityFramework不会削减额外数字。 Yep, looks like a bug. 是的,看起来像一个bug。 If someone know where to report it - please report or send link in comments. 如果有人知道在哪里举报 - 请在评论中报告或发送链接。

And what to do? 怎么办?

The solution is quite simple. 解决方案非常简单。 MySQL does not use milliseconds in Time and just discart it. MySQL在时间中不使用毫秒并且只是丢弃它。 So we can discart it before request. 所以我们可以在请求之前放弃它。 Final code: 最终代码:

TimeSpan currentTime = DateTime.Now.TimeOfDay;
// Re-creating TimeSpan to discart/cut milliseconds
currentTime = new TimeSpan(currentTime.Hours, currentTime.Minutes, currentTime.Seconds);
var count = context.Tasks.Where(p => p.ToTime > currentTime).Count();

And generated SQL would be always with 6 digits (000000). 生成的SQL总是带有6位数字(000000)。 That resolves the problem. 这解决了这个问题。

Bug? 错误?

As I said before that look like a bug. 正如我之前所说,看起来像一个bug。 So if you know where to report it - please report or send link in comments. 因此,如果您知道在哪里举报 - 请在评论中报告或发送链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM