关于NBearMapping中枚举类型转换的一个Bug

探讨了NBearMapping在枚举类型映射时遇到的问题及解决方案,尤其是在tinyint数据类型上的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NBearMapping是一个开源的对象映射工具,可用于任意类型对象、DataRow和DataReader对象间的透明映射。

开发者:Teddy Ma阿不

源代码地址:http://svn.cnblogs.com:8080/svn/NBear/trunk/src(可以用SVN客户端签出)

博客园开发中已大量使用NBearMapping,主要用于在数据访问层完成DataReader至实体类的映射。

今天在使用时遇到一个问题,问题发生在一个枚举类型属性的映射时,错误信息如下:

System.InvalidCastException: Specified cast  is  not valid.
   at System.Data.SqlClient.SqlBuffer.get_Int32()
   at System.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)
   at mf702c3fb37254bdb8276ca8f6f6c878e(Object , Object )
   at NBear.Mapping.ObjectMapper.ConvertObject(Object inputObject, Object outputObject)
   at NBear.Mapping.ObjectMapper.ConvertObject(Object inputObject)

之前经常进行枚举类型的映射,没遇到过问题,后来发现,是由于该属性在数据库中的数据类型是tinyint,改为int,问题就解决了。

为了找到问题的真正原因,不得不硬着头皮看NBearMapping的源代码。终于在DataReaderGetterGenerator.cs中找到问题的原因。

当遇到枚举类型时,NBearMapping调用IDataReader的GetInt32读取数据,当数据类型是tinyint时,就会引发“Specified cast is not valid”异常。

                 case  TypeCode.Int32:
                    getMethod 
=   typeof (IDataRecord).GetMethod( " GetInt32 " );
                    
break ;

 

解决方法:对于枚举类型时,调用IDataReader的GetValue读取数据:

             if  (memberValue.LocalType.IsEnum)
            {
                getMethod  =   typeof (IDataRecord).GetMethod( " GetValue " );
                mustBeUnBox  =   true ;               
            }


但这样就需要进行强制类型转换和拆箱操作,通过反射进行强制类型转换的代码如下:

             // Teddy 2008-2-2: added the  code section below to convert the object to the memberValue.LocalType
             if  (getMethod  ==   typeof (IDataRecord).GetMethod( " GetValue " ))
            {
                generator.Load(Type.GetTypeCode(memberValue.LocalType));
                generator.Call( typeof (Convert).GetMethod( " ChangeType " , BindingFlags.Instance  |  BindingFlags.Public  |  BindingFlags.Static,  null new  Type[] {  typeof ( object ),  typeof (TypeCode) },  null ));
            }


拆箱操作的代码:

ILGenerator.Emit(OpCodes.Unbox_Any, type)

如果不想增加这个拆箱操作,那就避免使用tinyint数据类型。

借这个随笔,想问一下大家在实际开发中用什么方法进行数据库与对象之间的映射?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值