Aug
03
教你利用反射将数据读入实体类
Posted by admin
IT技术问答:
请问那里有<人月神话>的中文电子版本下载?? [点击查看] 请教个temporary的问题 [点击查看] 备份数据问题 [点击查看] 紧急:ORACLE817不能安装于XEON的问题。在线等待。 [点击查看] 不装notes客户端能不能在IE中修改客户口令? [点击查看] asp中如何实现打开一个无状态栏和工具栏的窗口? [点击查看] 殇! [点击查看] 各位相亲们,俺差1000分就升级了,那位借个光?? [点击查看]
利用反射将数据读入实体类
在实际开发中,我们经常需要从数据库中读取数据并赋值给实体类的相应属性。比如:
publicrole[]getroles(intblogid)
{
system.collections.arraylistal=newsystem.collections.arraylist();
idatareaderreader=dbprovider.instance().getroles(blogid);
try
{
while(reader.read())
{
rolerole=newrole();
if(reader["roleid"]!=dbnull.value)
{
role.roleid=(int)reader["roleid"];
}
if(reader["name"]!=dbnull.value)
{
role.name=(string)reader["name"];
}
if(reader["description"]!=dbnull.value)
{
role.description=(string)reader["description"];
}
//readertoobject(reader,role);
al.add(role);
}
}
finally
{
reader.close();
}
return(role[])al.toarray(typeof(role));
}
对于上面的代码,我觉得有几点不优雅之处:
1、每次对role的属性进行赋值时,都要检查reader的值是否为dbnull,出现了很多重复代码
2、每次对role的属性进行赋值时,都要进行类型转换,而role属性的类型是已知的,是不是可以自动完成这样的转换?
3、每次对role的属性进行赋值时,都要进行role属性与数据库字段的对应。如果我们在设计数据库与实体类时,保证数据库字段与实体类属性采用同样的名称,那利用反射,我们可以通过代码自动进行属性与字段的对应。即使数据库字段与属性不同名,我们也可以通过更改查询语句,来做到这一点。
是不是可以对上面的代码进行改进,使代码变得更优雅?那优雅的代码应该是什么样的呢?如果我们用上面代码中注释的代码行readertoobject(reader,role);取代它之前的对role属性进行赋值的语句,是不是会使代码变得更优雅?readertoobject的作用就是自动完成将reader中的值写入到role中对应的属性中(前提是reader中的字段与role中对应的属性具有相同的名称)。现在我们的任务就是实现readertoobject,有了强大的武器—reflection,我们的任务就变得很轻松,也不多说了,下面的代码是我的实现方法:
privatevoidreadertoobject(idatareaderreader,objecttargetobj)
{
for(inti=0;i {
system.reflection.propertyinfopropertyinfo=targetobj.gettype().getproperty(reader.getname(i));
if(propertyinfo!=null)
{
if(reader.getvalue(i)!=dbnull.value)
{
if(propertyinfo.propertytype.isenum)
{
propertyinfo.setvalue(targetobj,enum.toobject(propertyinfo.propertytype,reader.getvalue(i)),null);
}
else
{
propertyinfo.setvalue(targetobj,reader.getvalue(i),null);
}
}
}
}
}
利用反射将数据读入实体类
在实际开发中,我们经常需要从数据库中读取数据并赋值给实体类的相应属性。比如:
publicrole[]getroles(intblogid)
{
system.collections.arraylistal=newsystem.collections.arraylist();
idatareaderreader=dbprovider.instance().getroles(blogid);
try
{
while(reader.read())
{
rolerole=newrole();
if(reader["roleid"]!=dbnull.value)
{
role.roleid=(int)reader["roleid"];
}
if(reader["name"]!=dbnull.value)
{
role.name=(string)reader["name"];
}
if(reader["description"]!=dbnull.value)
{
role.description=(string)reader["description"];
}
//readertoobject(reader,role);
al.add(role);
}
}
finally
{
reader.close();
}
return(role[])al.toarray(typeof(role));
}
对于上面的代码,我觉得有几点不优雅之处:
1、每次对role的属性进行赋值时,都要检查reader的值是否为dbnull,出现了很多重复代码
2、每次对role的属性进行赋值时,都要进行类型转换,而role属性的类型是已知的,是不是可以自动完成这样的转换?
3、每次对role的属性进行赋值时,都要进行role属性与数据库字段的对应。如果我们在设计数据库与实体类时,保证数据库字段与实体类属性采用同样的名称,那利用反射,我们可以通过代码自动进行属性与字段的对应。即使数据库字段与属性不同名,我们也可以通过更改查询语句,来做到这一点。
是不是可以对上面的代码进行改进,使代码变得更优雅?那优雅的代码应该是什么样的呢?如果我们用上面代码中注释的代码行readertoobject(reader,role);取代它之前的对role属性进行赋值的语句,是不是会使代码变得更优雅?readertoobject的作用就是自动完成将reader中的值写入到role中对应的属性中(前提是reader中的字段与role中对应的属性具有相同的名称)。现在我们的任务就是实现readertoobject,有了强大的武器—reflection,我们的任务就变得很轻松,也不多说了,下面的代码是我的实现方法:
privatevoidreadertoobject(idatareaderreader,objecttargetobj)
{
for(inti=0;i
system.reflection.propertyinfopropertyinfo=targetobj.gettype().getproperty(reader.getname(i));
if(propertyinfo!=null)
{
if(reader.getvalue(i)!=dbnull.value)
{
if(propertyinfo.propertytype.isenum)
{
propertyinfo.setvalue(targetobj,enum.toobject(propertyinfo.propertytype,reader.getvalue(i)),null);
}
else
{
propertyinfo.setvalue(targetobj,reader.getvalue(i),null);
}
}
}
}
}