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

因为公司业务的需要,系统对于时间的展示要有多元化的需求。这就要求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]
                        }
                    }


结束。


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值