Get DateTime as UTC with Dapper

前端 未结 4 1628
醉梦人生
醉梦人生 2020-12-04 15:23

I\'m using Dapper to map my entities to SQL Server CE. If I save a DateTime with Kind=Utc, when I read it back I get a DateTime with <

4条回答
  •  囚心锁ツ
    2020-12-04 15:55

    Just wanted to put my full solution here for seamlessly integrating DateTimeOffset / DateTimeOffset? fields/properties with a MySQL 5.7 database (which doesn't support DbType.DateTimeOffset) - based on @matt-jenkins answer above:

    public static class DapperExtensions
    {
        class DateTimeOffsetTypeHandler : SqlMapper.TypeHandler
        {
            public override void SetValue(IDbDataParameter parameter, DateTimeOffset value)
            {
                switch (parameter.DbType)
                {
                    case DbType.DateTime:
                    case DbType.DateTime2:
                    case DbType.AnsiString: // Seems to be some MySQL type mapping here
                        parameter.Value = value.UtcDateTime;
                        break;
                    case DbType.DateTimeOffset:
                        parameter.Value = value;
                        break;
                    default:
                        throw new InvalidOperationException("DateTimeOffset must be assigned to a DbType.DateTime SQL field.");
                }
            }
    
            public override DateTimeOffset Parse(object value)
            {
                switch (value)
                {
                    case DateTime time:
                        return new DateTimeOffset(DateTime.SpecifyKind(time, DateTimeKind.Utc), TimeSpan.Zero);
                    case DateTimeOffset dto:
                        return dto;
                    default:
                        throw new InvalidOperationException("Must be DateTime or DateTimeOffset object to be mapped.");
                }
            }
        }
    
    
        private static int DateTimeOffsetMapperInstalled = 0;
    
        public static void InstallDateTimeOffsetMapper()
        {
            // Assumes SqlMapper.ResetTypeHandlers() is never called.
            if (Interlocked.CompareExchange(ref DateTimeOffsetMapperInstalled, 1, 0) == 0)
            {
                // First remove the default type map between typeof(DateTimeOffset) => DbType.DateTimeOffset (not valid for MySQL)
                SqlMapper.RemoveTypeMap(typeof(DateTimeOffset));
                SqlMapper.RemoveTypeMap(typeof(DateTimeOffset?));
    
                // This handles nullable value types automatically e.g. DateTimeOffset?
                SqlMapper.AddTypeHandler(typeof(DateTimeOffset), new DateTimeOffsetTypeHandler());
            }
        }
    }
    

提交回复
热议问题