Типы NPoco / PetaPoco и Noda Time

Я только начинаю играть с NPoco, но пока не нашел в документации то, что мне нужно.

Например, предположим, что у меня есть поле Created, которое имеет значение Instant в моем домене, но DateTimeOffset установлено в формате UTC в моей базе данных. Есть ли способ преобразовать эти типы в NPoco?


person Matthew Vines    schedule 12.01.2014    source источник
comment
Не знаком с NPoco, но вы на правильном пути. В большинстве случаев ORM и DocDB потребуются специальные инструкции для работы с типами NodaTime. Я сделал это для RavenDB с JSON.net и работаю над решением для Entity Framework. Но вам нужно будет понять, как ваш конкретный ORM сопоставляет типы с базовыми параметрами ADO.Net и из них. В конечном итоге вам нужны Instant.ToDateTimeOffset() и Instant.FromDateTimeOffset(). Кроме того, для Instant было бы приемлемо использовать UTC DateTime, если хотите.   -  person Matt Johnson-Pint    schedule 12.01.2014
comment
Я вижу пример создания преобразователя значений в этом ответе. Вероятно, вы можете адаптировать это для работы с NodaTime Instant вместо того типа, для которого он был написан.   -  person Matt Johnson-Pint    schedule 12.01.2014
comment
@MattJohnson спасибо за ссылку, мне просто нужно потратить время на то, чтобы разобраться с этим интерфейсом IMapper.   -  person Matthew Vines    schedule 14.01.2014


Ответы (2)


Я расширил интерфейс, продемонстрированный Schotime, и построил его для нескольких типов NodaTime. Слишком большой для вставки сюда, поэтому вот GIST.

Обратите внимание, что он не включает ZonedDateTime, который должен быть сериализован в два разных поля, поэтому я не уверен, как NPoco справится с этим. Я также не включил Period, так как нет другого подходящего типа, кроме varchar.

Внимание! Этот код полностью не проверен. Я просто применяю то, что знаю о преобразованиях Noda Time, к переопределениям, которые иллюстрирует другой ответ. Пожалуйста, тщательно протестируйте его, прежде чем использовать в своем коде.

person Matt Johnson-Pint    schedule 15.01.2014
comment
SoureType и DestType в методе GetToDbConverter кажутся всегда одним и тем же типом. У меня есть кое-что работающее, предполагающее, что я хочу DateTimeOffset из Instant, так что спасибо, что выложили это. Мне любопытно, как я могу заставить его обрабатывать разные типы вывода, если захочу. - person Matthew Vines; 16.01.2014

Это довольно легко. Пример ниже — это то, что используется для работы с типами даты и времени 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. Привет, Адам

person Schotime    schedule 14.01.2014
comment
Мне любопытно, почему во время выполнения в GetToDbConverter DestType и SourceType всегда одного и того же типа. Я ожидал, как и Мэтт Джонсон, глядя на свой код, что destType будет соответствовать типу в базе данных. - person Matthew Vines; 16.01.2014
comment
Должен быть установлен тип столбца назначения. Либо используя атрибут [ColumnType], либо используя WithDbType свободную конфигурацию. - person Schotime; 17.01.2014