实体框架Azure SaveChanges - datetime,错误一小时

时间:2014-07-23 17:45:24

标签: sql entity-framework azure entity-framework-6

我正在使用EF6。我得到一个记录,然后我更新它。其中一列是日期时间列,但它不正确地更新。 Entity Framework生成的sql看起来是正确的,但是当执行sql时,数据库中的小时是不正确的。它似乎正确地更新了其他列。

sql,EF或Azure是否存在故障我不确定?

这是我的EF日志

UPDATE [dbo].[Fixtures]
SET [FixtureExternalId] = NULL, [SoccerFixtureId] = @0, [HomeTeamId] = @1, [AwayTeamId] = @2, [Date] = @3, [HomeScore] = @4, [AwayScore] = @5, [FixtureStatus] = @6, [InPlayTime] = @7, [CompetitionId] = @8, [CompetitionStage] = @9 WHERE ([FixtureId] = @10)
-- @0: '338066' (Type = Int32)
-- @1: '409' (Type = Int32)
-- @2: '842' (Type = Int32)
-- @3: '23/07/2014 16:00:00' (Type = DateTime2)
-- @4: '3' (Type = Int32)
-- @5: '0' (Type = Int32)
-- @6: '3' (Type = Int32)
-- @7: '89'' (Type = String, Size = -1)
-- @8: '15' (Type = Int32)
-- @9: '0' (Type = Int32)
-- @10: '12467' (Type = Int32)
-- Executing at 23/07/2014 18:31:37 +01:00

-- Completed in 34 ms with result: 1

正如你所看到的更新语句说的是15:00但是在执行了这个sql并且我做了一个sql select我得到的记录 2014-07-23 15:00:00.000

为什么时间一小时?

由于

2 个答案:

答案 0 :(得分:2)

确实,SQL Azure数据库使用UTC时区(请参阅this post)。您可以通过运行SELECT GETDATE()来验证它,这将返回UTC日期和时间。

您的应用程序似乎也使用UTC +1 时区(基于您的EF日志:“执行时间为23/07/2014 18:31:37 +01:00 “)。

但是,只要您在代码中使用System.DateTime并在数据库中使用DATETIME / DATETIME2,上述断言就无关紧要了。事实上:

  • SQL DATETIME / DATETIME2不存储时区信息。因此,通过设计,两者都是时区不可知的。根据{{​​3}},

  • 不会应用数据库服务器本身的时区偏移量
  • EF6也是时区不可知的。浏览完源代码后,我发现EF6忽略Kind值的System.DateTime属性,从不调用ToLocalTimeToUniversalTime,也不会调用任何其他时区偏移方法。日志格式化程序也很可靠,因为它只是对object.ToString的简单调用。

现在回到你的问题:

  

错误是sql,EF还是Azure我不确定?为什么是   时间一小时?

最可能的答案是,错误既不依赖于SQL,也不依赖于Azure。 以下是其他一些可能性:

  • 在观察之前,该值再次更新
  • 如果使用SQL数据工具等SQL管理工具观察值,可能该工具在显示时应用了一些转换
  • 触发器应用[日期]列的某些转换
  • 观察值(2014-07-23 15:00:00.000)是从数据库加载后调用DateTime.ToLocalTimeDateTime.ToUniversalTime方法的结果
  • 从数据库加载后,您观察到的值会被某些JSON或XML序列化/反序列化(请参阅this comment> XML的特殊情况)抵消

希望这有帮助。

答案 1 :(得分:0)

使用ISO 8601格式的datetimeoffset来保留本地:YYYY-MM-DDThh:mm:ss [.nnnnnnn] [{+ | - } hh:mm]作为偏移量或YYYY-MM-DDThh: mm:ss [.nnnnnnn] Z表示UTC(Azure工作时间为UTC)。

在代码中,您可以尝试DateTime.ToLocalTimeDateTime.ToUniversalTime