3

我有下表:

                  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_TIMESHIFT_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;

我收到以下错误:Operand data type time is invalid for add operator.

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

编辑:我试过两者都用.Add().CompareTo()但无济于事。

4

2 回答 2

4

我看到了一些问题。

让我们从这里开始:

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

DateTime.Now多次调用从来都不是一个好主意。您正在读取系统时钟三遍。此外,已经有一个用于此确切目的的属性,因此您可以这样做:

DateTime.Now.TimeOfDay

下一个问题:

c.SHIFT_TIME + c.SHIFT_DURATION

如果轮班时间是晚上 11:00,持续时间是 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

消息 8117,级别 16,状态 1,第 4 行
操作数数据类型时间对于加法运算符无效。

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

因此,当您进行原始查询时,time类型的列被添加在一起,这是不允许的。timetype的最大值是23:59:59.9999999,所以不可能得到我前面提到的 25 小时结果。

该怎么办?

要在 SQL 查询中操作日期和时间,您需要使用EntityFuntionsorSqlFunctions类的方法。这些将在您的查询中转换为 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 会将time输入类型隐式转换为 a datetime,以便它可以与DATEADD函数一起使用。它还将结果转换回一个time类型,因此您可以将其与您提供给查询的“现在”时间进行比较。

于 2013-07-11T05:58:29.923 回答
1

它不知道如何添加两个时间跨度。从 这个站点使用 TimeSpan.Add()

然后使用TimeSpan.Compare()


你在做什么

var query = from c in SHIFT
        where TimeSpan.Compare(c.SHIFT_TIME.Add(c.SHIFT_DURATION), 
                new TimeSpan(DateTime.Now.Hour,
                             DateTime.Now.Minute,
                             DateTime.Now.Second)).Equals(1)
        select c;

?

于 2013-07-10T19:05:28.983 回答