【问题标题】:Should it be possible to use a StoreGeneratedPattern of Computed on a DateTimeOffset column with EntityFramework?是否可以在 EntityFramework 的 DateTimeOffset 列上使用 Computed 的 StoreGeneratedPattern?
【发布时间】:2016-06-09 14:41:49
【问题描述】:

如果我在 Oracle DB 中有一个表,其中有一个名为 LastModified 的 TIMESTAMP(6) WITH TIMEZONE 列,并且我希望使用 EntityFramework 对其进行建模;是否可以将该列标记为 DatabaseGeneratedOption.Computed?

我有上述表,并已成功使用 EF6 和 Oracle.ManagedDataAccess.Client 创建模型优先/db 优先 edmx 模型。根据文档,TIMESTAMP(6) WITH TIMEZONE 列被映射为 DateTimeOffset,我手动将 LastModified 标记为 Computed。

这适用于 SELECT 语句,但是当我尝试进行更新时,我收到以下错误:

无法存储类型为“System.DateTime”的存储生成值 转换为所需的“System.DateTimeOffset”类型的值 ... 类型的成员“LastModified”。

深入了解异常和堆栈跟踪产生:

从“System.DateTime”到“System.DateTimeOffset”的无效转换。

在 System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider 提供程序)在 System.DateTime.System.IConvertible.ToType(类型类型,IFormatProvider 提供者)在 System.Convert.ChangeType(对象值,类型 转换类型,IFormatProvider 提供程序)在 System.Data.Entity.Core.Mapping.Update.Internal.PropagatorResult.AlignReturnValue(对象 值,EdmMember 成员)

我花了一些时间查看 EntityFramework 源代码,似乎处理返回数据库生成值的代码没有使用与 SELECT 或模型创建逻辑相同的映射逻辑。

这会导致TIMESTAMP(6) WITH TIMEZONE 在作为数据库生成值从数据库中检索时映射到 DateTime,然后在尝试将其转换为 DateTimeOffset 时失败。

这是已知/预期的行为吗?我错过了某个地方的设置吗?还是只有有限的类型子集可以在使用不是“无”的 StoreGeneratedPatten 时使用?

【问题讨论】:

    标签: c# entity-framework odp.net


    【解决方案1】:

    调试了 EntityFramework 并最终完全绕过它后,我发现问题出在提供程序 (Oracle.ManagedDataAccess.Client) 上。通过 EntityFramework 对具有 TIMESTAMP(6) WITH TIMEZONE 计算列的表进行 UPDATE 生成 sql,如下所示:

    DECLARE "COLUMNC_FOROUTPUT" TIMESTAMP WITH TIME ZONE;
    
    BEGIN
      UPDATE "SCHEMA"."TABLEA"
      SET "COLUMNB" = :p0
      WHERE ("COLUMNA" = :p1)
      RETURNING "COLUMNC" INTO "COLUMNC_FOROUTPUT";
    
      OPEN :p2 FOR 
      SELECT "COLUMNC_FOROUTPUT" AS "COLUMNC_FOROUTPUT" FROM dual;
    END;
    

    其中:p2 是一个参考光标。如果将上述 sql 和适当的参数直接馈送到 ODP.Net,则使用 ExecuteReader()reader.GetFieldValue<object>(0) 会产生一个类型为 DateTime 的对象,这与 TIMESTAMP(6) WITH TIMEZONE 应该映射到的对象相反 (DateTimeOffset)。

    我想需要另一个关于 ODP.Net、REF CURSORS 和 TIMESTAMP WITH TIME ZONE 映射的问题,因为我最初的问题的答案似乎是“是的,但如果您使用的是最新版本的 Oracle.ManagedDataAccess。客户作为提供者”。

    更新

    实际上,如果涉及引用游标,则没有区别,问题出在 Oracle.ManagedDataAccess.Client.OracleTypeMapper 类中,该类将带 TZ 的时间戳映射到 DateTime 而不是 DateTimeOffset。这将影响对 OracleDataReader 上的 GetFieldValue 的任何调用。

    我在 ODP.Net 论坛上询问了question,看看是否有人可以确认这是否是正确的行为。

    【讨论】:

      猜你喜欢
      • 2011-06-29
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-15
      • 2014-06-23
      相关资源
      最近更新 更多