ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-10-30 18:08:34  阅读:269  来源: 互联网

标签:timespan linq c entity-framework sql-server


我有下表:

                  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函数一起使用.它还会将结果转换回时间类型,因此您可以将其与提供给查询的“现在”时间进行比较.

标签:timespan,linq,c,entity-framework,sql-server
来源: https://codeday.me/bug/20191030/1969680.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有