Vb.net DbFunctions.TruncateTime在不同的服务器时区中的行为是否不同?

Vb.net DbFunctions.TruncateTime在不同的服务器时区中的行为是否不同?,vb.net,visual-studio-2015,datetimeoffset,dbfunctions,Vb.net,Visual Studio 2015,Datetimeoffset,Dbfunctions,我不确定我的题目是否完美,所以请允许我进一步解释一下 这里是一些测试数据的快照: 这是我的代码: 所以我的问题是: 订单日期为2015年9月27日和2015年9月22日的行按照上述逻辑正确查询-为每个请求的日期生成一行。但是——查询2015年8月14日的日期不会产生任何结果。如果有必要的话,我现在在-04:00时区。如果我将行数据中的时区[edit]更改为-04:00,则2 08/14/2015行查询正确 我曾在谷歌上搜索过这个问题的答案,但结果一无所获。有人能插手我的问题吗 [更新]:解决

我不确定我的题目是否完美,所以请允许我进一步解释一下

这里是一些测试数据的快照:

这是我的代码:

所以我的问题是:

订单日期为2015年9月27日和2015年9月22日的行按照上述逻辑正确查询-为每个请求的日期生成一行。但是——查询2015年8月14日的日期不会产生任何结果。如果有必要的话,我现在在-04:00时区。如果我将行数据中的时区[edit]更改为-04:00,则2 08/14/2015行查询正确

我曾在谷歌上搜索过这个问题的答案,但结果一无所获。有人能插手我的问题吗


[更新]:解决方法 这里有一个基于@PiotrAuguscik建议首先将查询转换为列表的解决方案(目前):

Dim orderRecs = (db.Orders.Where(Function(x) x.ClientLocationId = clientLocId AndAlso x.OrderNumber IsNot Nothing _
                AndAlso x.DateCompletedUtc IsNot Nothing).ToList) _
                .Where(Function(x) x.OrderDateLoc.Value.Date = showDate.Date) _
                .OrderByDescending(Function(x) x.OrderDateUtc)
这有点“硬”,但很管用。但是,我当然想知道为什么时区与DbFunctions.TruncateTime()有任何关系


[UPDATE#2]从Matt Johnson的答案中获得正确的解决方案代码

Dim orderRecs = db.Orders.Where(Function(x) x.ClientLocationId = clientLocId AndAlso x.OrderNumber IsNot Nothing _
                          AndAlso x.DateCompletedUtc IsNot Nothing AndAlso
                          (x.OrderDateLoc >= showDateDto AndAlso x.OrderDateLoc < showDateDto.AddDays(1))) _
                          .OrderByDescending(Function(x) x.OrderDateUtc)
Dim orderecs=db.Orders.Where(函数(x)x.ClientLocationId=clientLocId,并且x.OrderNumber不是空的_
而且x.DateCompletedUtc也不是什么都不是
(x.OrderDateLoc>=showDateDto和x.OrderDateLoc
有几件事:

  • 您的原始查询和解决方案都是可用的。决不能在
    WHERE
    子句中操纵比较的左侧。如果这样做,数据库将无法使用任何索引,并且随着数据量的增加,速度会越来越慢。而是执行范围查询

  • 您的表中似乎有
    datetimeoffset
    类型。这些值表示特定的时间时刻,因此与两个
    datetimeoffset
    值的比较是基于它们的UTC等效值进行的,而不是基于它们的本地显示时间。值也以这种方式编制索引

  • 并非每个人都在同一时间遵守相同的日历日期。你需要问自己,“我在找谁的约会?”

    • 如果是进行查询的人的日期,那么您的输入值应该反映该日期。不要将VB
      Date
      (这是一个
      System.DateTime
      )作为本地时间传递到查询中,而是传递基于UTC的
      DateTime
      ,或
      DateTimeOffset
      。请记住,您需要执行范围查询,以便将它们作为半开区间进行计算。换言之:

      // this example uses the local time zone, but there are other ways also.
      DateTimeOffset startDto = new DateTimeOffset(showDate.Date)
      DateTimeOffset endDto = new DateTimeOffset(showDate.Date.AddDays(1))
      
      // then in the query...
      ...   x.OrderDateLoc >= startDto && x.OrderDateLoc < endDto
      
      本质上,这使用字符串重新构建
      datetimeoffset
      ,同时保留偏移量,但将时间设置为午夜,这可能不是您真正想要做的。您可以在SQL Profiler中看到这一点


      • 这是对马特·约翰逊回应的回应。上面的查询不一定是不可搜索的,它取决于索引。当您将索引用作字段函数参数时,它将变得不可搜索。:)

        放置一个断点,看看
        DbFunctions.TruncateTime(x.OrderDateLoc)
        返回什么结果如何?@ZoffDino-谢谢你的回复。由于DbFunctions()函数只能出现在LINQ to Entities查询中,因此我不确定除了目前正在做的事情之外,我将如何做其他事情。请让我知道我是否忽略了一种方法。如果您使用的是SQL Server,您是否使用了探查器工具来查看正在执行的SQL?我猜被比较的实际值并不完全是你所期望的。有些东西可能会因时区的不同而发生变化。@jmcilhinney感谢您提供了可能的方向;我只是在开发IISExpress中进行测试-我从未使用过任何分析器(不确定如何使用,但如果可用的话,我会研究一些)。不知何故,时区影响了逻辑——我只是不知道为什么或者如何,因为我找不到任何文件表明时区与此有关。正如我在帖子(已编辑)中所说,如果我更改数据以反映-04:00时区,则行将显示在查询中。请参阅更新临时解决方案…@Matt_Johnson-非常感谢您的详细解释。这是非常有帮助和难以置信的信息。可悲的是,我从来没有想过要按照你建议的方式去做。。。我做到了,它工作得很好,而且都在你提到的指导方针范围内。我用来解决这个问题的代码已经被编辑到我的作品中。向你问好!
        // this example uses the local time zone, but there are other ways also.
        DateTimeOffset startDto = new DateTimeOffset(showDate.Date)
        DateTimeOffset endDto = new DateTimeOffset(showDate.Date.AddDays(1))
        
        // then in the query...
        ...   x.OrderDateLoc >= startDto && x.OrderDateLoc < endDto
        
        convert(datetimeoffset, convert(varchar(255), yourField, 102) + ' 00:00:00 ' + Right(convert(varchar(255), yourField, 121), 6), 102)