Skip to content

Instantly share code, notes, and snippets.

@mattjohnsonpint
Created January 15, 2014 07:59
Show Gist options
  • Save mattjohnsonpint/8432461 to your computer and use it in GitHub Desktop.
Save mattjohnsonpint/8432461 to your computer and use it in GitHub Desktop.
NPoco mapper for NodaTime
using System;
using NodaTime;
using NPoco;
namespace PocoNoda
{
public class NodaMapper : DefaultMapper
{
public override Func<object, object> GetFromDbConverter(Type DestType, Type SourceType)
{
if (DestType == typeof(Instant) || DestType == typeof(Instant?))
{
return x =>
{
if (x == null)
return null;
// You can store as a DATETIMEOFFSET with zero offset
if (x is DateTimeOffset)
return Instant.FromDateTimeOffset((DateTimeOffset) x);
// Or, you can store as a DATETIME or DATETIME2 and just use UTC by convention
if (x is DateTime)
return Instant.FromDateTimeUtc(DateTime.SpecifyKind((DateTime) x, DateTimeKind.Utc));
return x;
};
}
if (DestType == typeof(OffsetDateTime) || DestType == typeof(OffsetDateTime?))
{
return x =>
{
if (x == null)
return null;
// store as a DATETIMEOFFSET
if (x is DateTimeOffset)
return OffsetDateTime.FromDateTimeOffset((DateTimeOffset)x);
return x;
};
}
if (DestType == typeof(LocalDateTime) || DestType == typeof(LocalDateTime?))
{
return x =>
{
if (x == null)
return null;
// This can be stored as a DATETIME or DATETIME2
if (x is DateTime)
return LocalDateTime.FromDateTime((DateTime) x);
return x;
};
}
if (DestType == typeof(LocalDate) || DestType == typeof(LocalDate?))
{
return x =>
{
if (x == null)
return null;
// store using a DATE type in SQL
if (x is DateTime)
return LocalDateTime.FromDateTime((DateTime)x).Date;
return x;
};
}
if (DestType == typeof(LocalTime) || DestType == typeof(LocalTime?))
{
return x =>
{
if (x == null)
return null;
// store using a TIME type in SQL
if (x is TimeSpan)
return LocalTime.FromTicksSinceMidnight(((TimeSpan)x).Ticks);
return x;
};
}
if (DestType == typeof(Duration) || DestType == typeof(Duration?))
{
return x =>
{
if (x == null)
return null;
// You can use a TIME type in SQL, but it's going to be limited to less than 24 hours.
if (x is TimeSpan)
return Duration.FromTimeSpan((TimeSpan) x);
// If stored as 32-bit integer, you'll need to set the precision.
// Here, it's using seconds.
if (x is int)
return Duration.FromSeconds((int) x);
// For full storage of a Duration, you'll need to store as a 64-bit integer.
if (x is long)
return Duration.FromTicks((long) x);
return x;
};
}
return base.GetFromDbConverter(DestType, SourceType);
}
public override Func<object, object> GetToDbConverter(Type DestType, Type SourceType)
{
if (SourceType == typeof(Instant) || SourceType == typeof(Instant?))
{
return x =>
{
if (x == null)
return null;
// You can store as a DATETIMEOFFSET with zero offset
if (DestType == typeof (DateTimeOffset) || DestType == typeof (DateTimeOffset?))
return ((Instant) x).ToDateTimeOffset();
// Or, you can store as a DATETIME or DATETIME2 and just use UTC by convention
if (DestType == typeof(DateTime) || DestType == typeof(DateTime?))
return ((Instant) x).ToDateTimeUtc();
return x;
};
}
if (SourceType == typeof(OffsetDateTime) || SourceType == typeof(OffsetDateTime?))
{
return x =>
{
if (x == null)
return null;
// store as a DATETIMEOFFSET
if (DestType == typeof(DateTimeOffset) || DestType == typeof(DateTimeOffset?))
return ((OffsetDateTime)x).ToDateTimeOffset();
return x;
};
}
if (SourceType == typeof(LocalDateTime) || SourceType == typeof(LocalDateTime?))
{
return x =>
{
if (x == null)
return null;
// This can be stored as a DATETIME or DATETIME2
if (DestType == typeof (DateTime) || DestType == typeof (DateTime?))
return ((LocalDateTime) x).ToDateTimeUnspecified();
return x;
};
}
if (SourceType == typeof(LocalDate) || SourceType == typeof(LocalDate?))
{
return x =>
{
if (x == null)
return null;
// store using a DATE type in SQL
if (DestType == typeof(DateTime) || DestType == typeof(DateTime?))
return ((LocalDate)x).AtMidnight().ToDateTimeUnspecified();
return x;
};
}
if (SourceType == typeof(LocalTime) || SourceType == typeof(LocalTime?))
{
return x =>
{
if (x == null)
return null;
// store using a TIME type in SQL
if (DestType == typeof (TimeSpan) || DestType == typeof (TimeSpan?))
return TimeSpan.FromTicks(((LocalTime) x).TickOfDay);
return x;
};
}
if (SourceType == typeof(Duration) || SourceType == typeof(Duration?))
{
return x =>
{
if (x == null)
return null;
// You can use a TIME type in SQL, but it's going to be limited to less than 24 hours.
if (DestType == typeof (TimeSpan) || DestType == typeof (TimeSpan?))
return ((Duration) x).ToTimeSpan();
// If stored as 32-bit integer, you'll need to set the precision.
// Here, it's using seconds.
if (DestType == typeof (int) || DestType == typeof (int?))
return (int) ((Duration) x).ToTimeSpan().TotalSeconds;
// For full storage of a Duration, you'll need to store as a 64-bit integer.
if (DestType == typeof(long) || DestType == typeof(long?))
return ((Duration)x).Ticks;
return x;
};
}
return base.GetToDbConverter(DestType, SourceType);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment