NPoco / PetaPoco and Noda Time types

1.1k Views Asked by At

I'm just starting to play around with NPoco, but as of yet I haven't located what I need in the docs.

For instance, let's say I have a field Created, which is an Instant in my domain, but a DateTimeOffset set to UTC in my database. Is there a way to have NPoco convert these types?

2

There are 2 best solutions below

1
On BEST ANSWER

I expanded on the interface that Schotime demonstrated and built it out for several NodaTime types. Too big to paste here, so here is a GIST.

Note that it doesn't include ZonedDateTime, which would have to be serialized to two different fields, so I'm not sure how NPoco would deal with that. I also didn't include Period, since there's no great corresponding type other than a varchar.

Warning: This code is completely untested. I'm just applying what I know about Noda Time conversions to the overrides that the other answer illustrated. Please test it thoroughly before using in your code.

2
On

This is pretty easy. The example below is what is used to deal with the PostgreSQL datetime types, however you can probably adapt this code fairly easy.

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);
    }
}

If you have any further questions post a question to the issues page on github. Cheers, Adam