运算符数据类型的时间对于加法运算符无效

我有下表:

                  SHIFT
 ----------------------------------------
| SHIFT_ID | SHIFT_TIME | SHIFT_DURATION |
| -------------------------------------- |
| 1        | 00:00:00   | 01:00:00       |
| 2        | 01:00:00   | 01:00:00       |
| 3        | 02:00:00   | 01:00:00       |
 ----------------------------------------

此处,SHIFT_TIME和SHIFT_DURATION的类型为TimeSpan.

现在,当我运行以下查询时:

var query = from c in SHIFT
            where c.SHIFT_TIME + c.SHIFT_DURATION >=
            new TimeSpan(DateTime.Now.Hour,
                         DateTime.Now.Minute,
                         DateTime.Now.Second)
            select c;

我收到以下错误:操作数数据类型时间对于添加运算符无效.

为什么这样做呢?我该如何避免这个错误?

编辑:我尝试使用.Add()和.CompareTo()无济于事.

解决方法:

我看到了一些问题.

让我们从这里开始:

new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second)

多次调用DateTime.Now绝不是一个好主意.您正在读取系统时钟三遍.另外,已经有一个用于此确切目的的属性,因此您可以执行以下操作:

DateTime.Now.TimeOfDay

下一个问题:

c.SHIFT_TIME + c.SHIFT_DURATION

如果轮班时间是11:00 PM,持续时间是2个小时,那么您可能希望是1:00,但是您将获得25个小时. (实际上,您将获得“ 1天1小时”.)因此,当您将其设置为一天中的某个时间(例如12:30 AM)时,可能会得到与预期不同的结果.

下一个问题:

您没有提到这一点,但看起来您实际上是在将LINQ-to-Entities作为附加到SQL Server的实体框架的一部分使用. (我更新了您的标记.)我可以知道,因为您收到的错误消息实际上是SQL Server错误消息.您可以像这样在SQL Server Management Studio中重现它:

declare @t1 time, @t2 time
set @t1 = '1:00'
set @t2 = '1:00'
print @t1 + @t2

Msg 8117, Level 16, State 1, Line 4
Operand data type time is invalid for add operator.

虽然可以在.Net中添加两种TimeSpan类型,但不能在SQL Server中添加两种时间类型.这是因为时间旨在表示一天中的某个时间,而TimeSpan主要表示所测量的时间长度. (从技术上讲,我上面提到的DateTime.TimeOfDay属性违背了TimeSpan类型的设计目的,但是由于.Net中没有Time类型,因此可以使用它.)

因此,当您执行原始查询时,时间类型的列会加在一起,这是不允许的.时间类型的最大值是23:59:59.9999999,因此不可能获得我之前提到的25小时结果.

该怎么办?

要在SQL查询中操作日期和时间,您需要使用EntityFuntionsSqlFunctions类的方法.这些将转换为查询中SQL的本机函数.

我相信这会满足您的需求:

var query = from c in SHIFT
            where EntityFunctions.AddMinutes(c.SHIFT_TIME,
                    EntityFunctions.DiffMinutes(TimeSpan.Zero, c.SHIFT_DURATION))
                  >= DateTime.Now.TimeOfDay
            select c;

这将建立一个类似于以下内容的sql查询(假设现在是1:00):

SELECT * FROM SHIFT WHERE DATEADD(minute,
                                    DATEDIFF(minute, 0, SHIFT_DURATION),
                                    SHIFT_TIME
                                 ) >= '1:00'

SQL Server会将时间输入类型隐式转换为日期时间,以便可以与DATEADD函数一起使用.它还会将结果转换回时间类型,因此您可以将其与提供给查询的“现在”时间进行比较.

上一篇:c#-以xaml格式设置TimeSpan值


下一篇:时间格式格式化为TotalMilliseconds