首页 | IT新闻 | 硬件 | 操作系统 | 开发 | 网络编程 | 数据库 | 热门框架 | 网络安全 | 组网 | 建站指南 | 网页制作 | 特效 | 实用技巧 | 服务器 | 办公 | QQ | 探索 | 社区

  • 技术部落
  • 部落首页 > 程序开发 > C/C#/C++ > 正文
  • 教你利用反射将数据读入实体类
      2007-3-20  来源:网络资源  编辑:Jsbulo  热度:

    利用反射将数据读入实体类

    在实际开发中,我们经常需要从数据库中读取数据并赋值给实体类的相应属性。 比如:

    public Role[] GetRoles(int BlogID)
    {
    System.Collections.ArrayList al=new System.Collections.ArrayList();
    IDataReader reader=DbProvider.Instance().GetRoles(BlogID);
    try
    {
    while(reader.Read())
    {
    Role role=new Role();
    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,我们的任务就变得很轻松, 也不多说了,下面的代码是我的实现方法:

    private void ReaderToObject(IDataReader reader,object targetObj)
    {
    for(int i=0;i {
    System.Reflection.PropertyInfo propertyInfo=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);
    }
    }
    }
    }
    }