【问题标题】:NPoco / PetaPoco and Noda Time typesNPoco / PetaPoco 和 Noda 时间类型
【发布时间】:2014-01-31 06:53:48
【问题描述】:

我刚刚开始使用 NPoco,但到目前为止我还没有在文档中找到我需要的内容。

例如,假设我有一个字段Created,它在我的域中是一个Instant,但在我的数据库中将DateTimeOffset 设置为UTC。有没有办法让 NPoco 转换这些类型?

【问题讨论】:

  • 不熟悉 NPoco,但您走在正确的轨道上。在大多数情况下,ORM 和 DocDB 需要自定义指令才能使用 NodaTime 类型。我已经使用 JSON.net 为 RavenDB 完成了这项工作,并且正在为实体框架开发解决方案。但是您需要了解您的特定 ORM 如何将类型映射到底层 ADO.Net 参数/从底层 ADO.Net 参数映射类型。最终你需要Instant.ToDateTimeOffset()Instant.FromDateTimeOffset()。此外,对于 Instant,如果您愿意,也可以使用 UTC DateTime
  • 快速浏览了一下,我看到 PetaPoco 提到了在他们的main list of features 上安装“值转换器”的能力。你应该进一步探索。我没有看到 NPoco 有类似的东西,所以我猜你必须修改他们的源代码。祝你好运!
  • 我在this answer 中看到了一个创建值转换器的示例。您可能可以将其调整为使用 NodaTime Instant 而不是为其编写的类型。
  • @MattJohnson 感谢您的链接,我只需要花时间弄清楚 IMapper 界面。

标签: petapoco nodatime npoco


【解决方案1】:

我扩展了 Schotime 演示的界面,并为几种 NodaTime 类型构建了它。太大,无法粘贴在这里,所以here is a GIST

请注意,它不包括ZonedDateTime,它必须被序列化为两个不同的字段,所以我不确定 NPoco 将如何处理它。我也没有包含Period,因为除了varchar 之外没有很好的对应类型。

警告:此代码完全未经测试。我只是将我对 Noda Time 转换的了解应用于另一个答案说明的覆盖。在您的代码中使用之前,请对其进行彻底测试。

【讨论】:

  • 方法 GetToDbConverter 中的 SoureType 和 DestType 似乎总是相同的类型。我确实有一些工作假设我想要一个来自 Instant 的 DateTimeOffset,所以谢谢你把它放在那里。如果我愿意,我很好奇如何让它处理不同的输出类型。
【解决方案2】:

这很容易。下面的示例用于处理 PostgreSQL 日期时间类型,但是您可以相当容易地修改此代码。

public class Mapper : DefaultMapper
{
    public override Func<object, object> GetFromDbConverter(Type DestType, Type SourceType)
    {
        if (DestType == typeof(DateTimeOffset) || DestType == typeof(DateTimeOffset?)
            || DestType == typeof(DateTime) || DestType == typeof(DateTime?))
        {
            return x =>
            {
                if (x is NpgsqlTimeStampTZ)
                {
                    if (DestType == typeof(DateTime))
                        return (DateTime)((NpgsqlTimeStampTZ)x);
                    if (DestType == typeof(DateTime?))
                        return (DateTime?)((NpgsqlTimeStampTZ)x);
                    if (DestType == typeof(DateTimeOffset))
                        return (DateTimeOffset)((NpgsqlTimeStampTZ)x);
                    if (DestType == typeof(DateTimeOffset?))
                        return (DateTimeOffset?)((NpgsqlTimeStampTZ)x);
                }
                if (x is NpgsqlTimeStamp)
                {
                    if (DestType == typeof(DateTime))
                        return (DateTime)((NpgsqlTimeStamp)x);
                    if (DestType == typeof(DateTime?))
                        return (DateTime?)((NpgsqlTimeStamp)x);
                }
                if (x is NpgsqlDate)
                {
                    if (DestType == typeof(DateTime))
                        return (DateTime)((NpgsqlDate)x);
                    if (DestType == typeof(DateTime?))
                        return (DateTime?)((NpgsqlDate)x);
                }

                return x;
            };
        }

        return base.GetFromDbConverter(DestType, SourceType);
    }

    public override Func<object, object> GetToDbConverter(Type DestType, Type SourceType)
    {
        if (SourceType == typeof(Instance)) {
            return x => { return ((Instance)x).ToDateTimeOffset(); } // etc or something like this
        }

        return base.GetToDbConverter(DestType, SourceType);
    }
}

如果您有任何其他问题,请将问题发布到 github 上的问题页面。 干杯, 亚当

【讨论】:

  • 我很好奇为什么在运行时,在 GetToDbConverter 中,为什么 DestType 和 SourceType 总是相同的类型。我希望,正如 Matt Johnson 看到他的代码一样,destType 将对应于数据库中的类型。
  • 必须设置目标列类型。使用[ColumnType] 属性或使用WithDbType fluent 配置。
猜你喜欢
  • 2012-12-20
  • 2013-08-22
  • 2014-03-09
  • 2016-05-28
  • 2012-02-07
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
相关资源
最近更新 更多