"TIMESTAMP WITH TIME ZONE" <--> DateTImeOffset 映射不会在 INSERT 命令(实体框架 + Oracle)上传递区域部分



我使用EF(EDMX模型-DB优先)将"TIMESTAMP WITH TIME ZONE"映射到DateTimeOffset。当我将DateTimeOffset提交给Oracle时,Zone部分保存不正确。

因此,例如,如果使用模型插入值29/02/2012 10:10:10 +04:00,那么实际存储在Oracle中的值是29/02/2012 10:10:10 +02:00(假设+02:00是本地区域)请注意,在查询数据时,映射工作得很好。只有INSERT(通过ObjectContext.SaveChanges())中断。。。

我已经调试到"Oracle.DataAccess.dll"(使用ILSpy:)中,发现EF的映射代码省略了区域("Oracle数据提供程序"只传递DateTimeOffset.DateTime)。

有人知道变通办法吗?

提前感谢Eli

BTW:我使用的是.net4、EF4、Oracle 11g、ODAC 11.2 Release 4(11.2.0.3.0)

您可以尝试动态设置会话时区,它"在TIMESTAMP值转换为TIMESTAMP WITH时生效时区或具有本地时区数据类型的TIMESTAMP".

当然,这是一个可怕的黑客攻击,也是因为您不能直接通过SQL执行alter会话。你必须使用类似的东西

begin DBMS_UTITLITY.EXEC_DDL_STATEMENT ('Alter Session Set TIME_ZONE = ''+04:00'''); end;

Oracle承认这是一个错误https://community.oracle.com/thread/2360615?tstart=0.他们很难过它已经在13851978错误中修复了。但我在11.2.0.3.0上对oracle客户端的测试仍然失败。

解决方案是@HAL 9000建议在保存到数据库之前,将会话的时区设置为DatetimeOffset的时间跨度中的小时和分钟。但是,如果一个对象中有多个DatetimeOffset属性,并且这些属性在DatetimeOffset内具有不同的时间跨度,则这将不起作用。

另一种选择是用第三方数据提供商(如Devart的DotConnect)取代ODP.NET(我已经测试过了,它对我很有效)。stackoverflow中有一个关于不同数据提供者的比较https://stackoverflow.com/a/8298684/1443505.

将偏移量存储在数据库中可能不利于夏令时偏移量管理。在目的不受影响的情况下,最好始终使用时区名称而不是偏移值。

--To store actual time and timezone value
to_timestamp_tz('10-SEP-2014 01:40:00.000000000 US/Pacific','DD-MON-YYYY HH24:MI:SS.FF9 TZR')
--To store actual time at timezone converted to UTC timezone value for uniformity
to_timestamp_tz('10-SEP-2014 01:40:00.000000000 US/Pacific','DD-MON-YYYY HH24:MI:SS.FF9 TZR') at time zone 'UTC'

最新更新