CN.Text开发笔记—利用反射将数据读入实体类

博客指出在实际开发中,从数据库读取数据赋值给实体类属性的代码存在不优雅之处,如重复检查、类型转换和手动对应字段等。提出利用反射实现ReaderToObject方法自动完成赋值,还可通过配置文件映射。同时强调开发中应减少重复代码,不必拘泥设计模式。

在实际开发中,我们经常需要从数据库中读取数据并赋值给实体类的相应属性。在.Text的DataDTOProvider中存在大量这样的代码, 比如:

None.gifpublic Role[] GetRoles(int BlogID)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif            System.Collections.ArrayList al
=new System.Collections.ArrayList();
InBlock.gif            IDataReader reader
=DbProvider.Instance().GetRoles(BlogID);
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
while(reader.Read())
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    Role role
=new Role();
InBlock.gif                    
if(reader["RoleID"]!=DBNull.Value)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        role.RoleID
=(int)reader["RoleID"];
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
if(reader["Name"]!=DBNull.Value)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        role.Name
=(string)reader["Name"];
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
if(reader["Description"]!=DBNull.Value)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        role.Description
=(string)reader["Description"];
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
//ReaderToObject(reader,role);
InBlock.gif
                    al.Add(role);
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                reader.Close();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return (Role[])al.ToArray(typeof(Role));
InBlock.gif        
ExpandedBlockEnd.gif        }


对于上面的代码,我觉得有几点不优雅之处:
1、每次对Role的属性进行赋值时,都要检查reader的值是否为DBNull,出现了很多重复代码
2、每次对Role的属性进行赋值时,都要进行类型转换, 而Role属性的类型是已知的,是不是可以自动完成这样的转换?
3、每次对Role的属性进行赋值时,都要进行Role属性与数据库字段的对应。如果我们在设计数据库与实体类时,保证数据库字段与实体类属性采用同样的名称,那利用反射,我们可以通过代码自动进行属性与字段的对应。即使数据库字段与属性不同名,我们也可以通过更改查询语句,来做到这一点。
是不是可以对上面的代码进行改进,使代码变得更优雅?那优雅的代码应该是什么样的呢?如果我们用上面代码中注释的代码行ReaderToObject(reader,role);取代它之前的对Role属性进行赋值的语句,是不是会使代码变得更优雅?ReaderToObject的作用就是自动完成将reader中的值写入到role中对应的属性中(前提是reader中的字段与role中对应的属性具有相同的名称)。现在我们的任务就是实现ReaderToObject, 有了强大的武器—Reflection,我们的任务就变得很轻松, 也不多说了,下面的代码是我的实现方法:

None.gifprivate void ReaderToObject(IDataReader reader,object targetObj)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif{
InBlock.gif            
for(int i=0;i<reader.FieldCount;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Reflection.PropertyInfo propertyInfo
=targetObj.GetType().GetProperty(reader.GetName(i));
InBlock.gif                
if(propertyInfo!=null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if(reader.GetValue(i)!=DBNull.Value)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        propertyInfo.SetValue(targetObj,reader.GetValue(i),
null);
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

ReaderToObject可以将reader中的数据读入到任何实体类中。数据库字段与实体类属性的映射原则是名称相同。当然,我们也可以通过配置文件来进行两者映射。

    个人想法:在开发中,面对那么多设计思想和设计模式,常常令人感到迷惑,当你把更多的精力放在选用哪个设计思想或设计模式时,我觉得不要忽略很重要的一点,尽可能地减少重复代码,只要我们能有效地减少重复代码,我们采用的方法就是好方法,而不要太在乎采用了哪种模式。就像独孤九剑,正因为摆脱了传统招式的束缚,才能战无不胜!

转载于:https://www.cnblogs.com/dudu/archive/2004/09/12/42389.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值