NPoco / PetaPoco and Noda Time types

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 answers

1
Matt Johnson-Pint 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
Schotime 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