Dapper.Net 框架从数据库返回时间指定DateTimeKind

来源:互联网 发布:java对象存储数据库 编辑:程序博客网 时间:2024/06/06 07:08

因为公司业务的需要,系统对于时间的展示要有多元化的需求。这就要求DateTime类型要有DateTimeKind。

ORM我采用的是Dapper.Net,其原生态不支持DateTimeKind的指定。所以只能分析源代码进行修改。忙活了大半个晚上,终于解决了,记录一下。

第一步,当然是定义Attribute

    /// <summary>    /// 表字段    /// </summary>    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]    public class ColumnAttribute : Attribute    {        /// <summary>        /// 指定返回时间类型的DateTimeKind        /// </summary>        public DateTimeKind DateTimeKind { get; set; }                /// <summary>        ///         /// </summary>        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]        public ColumnAttribute()        {        }    }


 

第二步,在实体上打标签

    public class User    {        [Column(DateTimeKind = DateTimeKind.Utc)]        public DateTime AddTime { get; set; }    }

 

第三步,将DateTime.SpecifyKind方法信息在Dapper.Net 的SqlMapper类中初始化

static MethodInfo specifyKind = typeof(DateTime).GetMethod("SpecifyKind", BindingFlags.Static | BindingFlags.Public);


 

最后一步,在SqlMapper 的GetTypeDeserializer方法中增加代码

                    if (specializedConstructor == null)                    {                        //Add by Arden 2013/10/17                         //数据库返回时间 指定 DateTimeKind                        if (item.MemberType == typeof(DateTime))                        {                            var entityInfo = EntityCache.GetEntityInfo(type);                            var dateTimeAttr = entityInfo.GetPropertyInfo(item.Property.Name).ColumnAttribute;                            if (dateTimeAttr != null && dateTimeAttr.DateTimeKind != DateTimeKind.Unspecified)                            {                                il.Emit(OpCodes.Ldc_I4_S, (byte)dateTimeAttr.DateTimeKind);                                il.Emit(OpCodes.Call, specifyKind);                            }                        }                        //Add End                        // Store the value in the property/field                        if (item.Property != null)                        {                            if (type.IsValueType)                            {                                il.Emit(OpCodes.Call, DefaultTypeMap.GetPropertySetter(item.Property, type)); // stack is now [target]                            }                            else                            {                                il.Emit(OpCodes.Callvirt, DefaultTypeMap.GetPropertySetter(item.Property, type)); // stack is now [target]                            }                        }                        else                        {                            il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]                        }                    }


结束。


 

 

原创粉丝点击