2

我对 DateTimeOffset 列的 Linq 查询总是抛出 InvalidTimeZoneException。数据似乎是正确的。知道发生了什么吗?

细节:

    Oracle Column:  CREATED_DATETIME  TIMESTAMP(0) WITH TIME ZONE

    EF MAPPING: public Nullable<System.DateTimeOffset> CREATED_DATETIME { get; set; }

    DataAccess: ODP.net Oracle.DataAccess

    Data Sample: (Timezone column available but not used)

        CREATED_DATETIME              TIMEZONE_NAME
        8/16/2013 5:06:05 PM +00:00   US/Central
        8/16/2013 5:35:06 PM +00:00   US/Mountain

代码:

var q = from isr in pc.ISRs
                select isr.CREATED_DATETIME;
        try
        {
            DateTimeOffset? value = q.First();
        }
        catch (InvalidTimeZoneException tze)
        {
            throw new ApplicationException(tze.Message);
        }
        catch (Exception e)
        {
            throw new ApplicationException(e.Message);
        }

        var orders = from o in q select o;
4

1 回答 1

1

Oracle 的TIMESTAMP WITH TIME ZONE类型(又名TIMESTAMPTZ)是一个有趣的生物。它存储日期、时间和固定的“时区偏移”“时区区域名称”。

当有一个固定的偏移量时,DateTimeOffset.Net 中的类型将是一个很好的匹配,Entity Framework 使用它作为默认值也就不足为奇了。(虽然从技术上讲,映射可能来自底层的 ODP.net 提供程序,而不是来自 EF。)

但是当它是一个时区区域名称时,就会出现问题:

  • 这些时区名称是 IANA 时区,不能直接用于TimeZoneInfo类。他们需要翻译。请参阅时区标签 wiki中有关时区数据库的部分。

  • .NET 没有任何类型代表时区DateTime或与时区DateTimeOffset配对。

  • Oracle 数据实际上不包括时区名称。相反,它包含一个指向 Oracle 数据库内系统数据中的 id 的指针。因此,必须在与数据库的连接仍处于打开状态时从原始位中解析此名称。不久前,我回答了一个关于这个以及它与 Java 的关系的问题。您可以在此处阅读我的回复,该回复主要仍适用于 .NET。(虽然我确信 ODP.net 中的实现完全不同。)

值得指出的是,Noda Time库包括 IANA 时区数据和ZonedDateTime可以完全代表 Oracle 的类型TIMESTAMPTZ。没有直接映射,但我想ZonedDateTime在调用你的 Oracle 数据库时应该可以构造一个。

但是,目前不支持 Noda Time with Entity Framework,所以这会妨碍这里。(这是我的议程,但我还没有深入研究它。)

因此,最有可能的是,您能够TIMESTAMPTZ在 Entity Framework 中使用该类型的唯一方法是确保您仅使用固定偏移区域。将它与 Oracle“时区区域名称”一起使用是行不通的。至少——还没有。

真的很可惜。区域名称是一个很好的功能,因为这样您就可以自动获得将夏令时更改纳入计算的好处。

于 2013-09-11T00:47:11.473 回答