日期:2014-05-18  浏览次数:20526 次

高分求一个ADO.NET方面的问题
查询返回一个SqlDataReader,需要将值转换为正确的类型

我一般这么转换:
MyObject.StringValue   =   Convert.ToString(reader[ " "])
MyObject.Int32Value   =   Convert.ToInt32(reader[ " "])

...   ...


还有这样的:
MyObject.StringValue   =   (String)(reader[ " "])
MyObject.Int32Value   =   (Int32)(reader[ " "])

...   ...

不知道哪种方法效率高,哪种方法好一些?

------解决方案--------------------
这个有意思,有时间测试下

不知道 Convert 内部具体如何实现

方式 2 ,对于值类型,实质上,是一个拆箱的过程
对应引用类型,如 string,应该方式2 更快

事实上, 通过 DataReader 读取数据,效率最好的应该是
使用 GetXXX 方法,直接从数据库类型映射到 .net 类型,
特别对于值类型,不需要经历装箱、拆箱的过程

as

int colValue0 = MyDataReader.GetInt32(0);
double colValue2 = MyDataReader.GetDouble(1);
string colValue3 = MyDataReader.GetString(2);

当然由于,使用索引访问,会带来后期维护的复杂性,
因此,一种折中的方式是,

int colValue0 = MyDataReader.GetInt32(MyDataReader.GetOrdinal( "ColName1 "));
double colValue2 = MyDataReader.GetDouble(MyDataReader.GetOrdinal( "ColName2 "));
string colValue3 = MyDataReader.GetString(MyDataReader.GetOrdinal( "ColName3 "));

显然,这样的手动coding,确实累人,
不过,现在基本都是基于代码生成器,

------解决方案--------------------
假设处理了reader[ "abc "]可能返回DBNull的问题,或者假设肯定查询到可靠的值。

如果数据库查询返回 Int32类型的字段,对于 Convert.ToInt32(reader[ "abc "])来说,首先把reader[ "abc "])这个object强制类型转换为 IConvertible 类型(实际是接口),然后调用这个接口的 ToInt32 函数,这个函数声明了返回一个Int32类型的数值,并且内部执行一句“return this;”。

而如果写(Int32)(reader[ "abc "]),则仅仅强制类型转换为Int32类型。

强制类型转换其实并不执行任何代码。所以你可以看成第二种方式不需要任何代价,而前者需要一个完整调用函数的开销。

如果你明知reader[ "abc "]返回的内容是Int32,如果再使用Convert.ToInt32就是多余的了。