菜鸟一枚,入园已有两年三个月,这还是第一次写博客,请各位大神斧正。

这是我写的一个工具类,通常我们从数据库查询到一个  DataReader  或者是  一个 Table , 想要转换成 一个 list 或者是 一个model 的话 , 一般情况下是使用foreach 循环reader或是tablerows,然后在循环内创建个对象,通过reader[“列名”]来赋值对象的属性。如果表的字段少的话,用这种方式还可以,速度也快一点。但是如果后续还会增加字段的话,那就非常麻烦了,要改很多地方。这工作量太大了,而且还很容易出错。所以这个时候使用反射来转换的话就非常便捷了。我们只管增加字段,改一下数据表对应的model,调用这个工具类的方法,传入相对应的参数就能得到想要的结果。

诶,文笔不好,直接上代码吧。

 public class DynamicGeneric
{
/// <summary>
/// table转list
/// </summary>
/// <typeparam name="T">list类型</typeparam>
/// <param name="obj">model对象</param>
/// <param name="table">数据源table</param>
/// <returns>list</returns>
public static List<T> FillListByDataTable<T>(T obj, DataTable table)
{ Type type = obj.GetType(); List<T> list = new List<T>(); PropertyInfo[] properties = type.GetProperties();//model对象的属性集合 DataColumnCollection dcc = table.Columns;//列集合 foreach (DataRow row in table.Rows)
{
//复制一个model对象
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
stream.Position = ;
T newObj = (T)formatter.Deserialize(stream); foreach (PropertyInfo pro in properties)
{
Type tp = pro.PropertyType; if (dcc.Contains(pro.Name.ToString()))
{
if (!string.IsNullOrEmpty(row[pro.Name].ToString()))
{
//判断字段类型
if (tp.Name != "Nullable`1")
{
pro.SetValue(newObj, Convert.ChangeType(row[pro.Name], tp, null));
}
if (tp.Name != "Nullable`1")
{
pro.SetValue(newObj, Convert.ChangeType(row[pro.Name], tp));
}
else if (tp.FullName.IndexOf("System.DateTime") > )
{
pro.SetValue(newObj, Convert.ChangeType(row[pro.Name], typeof(DateTime), null));
}
else if (tp.FullName.IndexOf("System.Int32") > )
{
pro.SetValue(newObj, Convert.ChangeType(row[pro.Name], typeof(Int32), null));
}
else if (tp.FullName.IndexOf("System.Int64") > )
{
pro.SetValue(newObj, Convert.ChangeType(row[pro.Name], typeof(Int64), null));
}
else if (tp.FullName.IndexOf("System.Decimal") > )
{
pro.SetValue(newObj, Convert.ChangeType(row[pro.Name], typeof(Decimal), null));
}
else if (tp.FullName.IndexOf("System.Boolean") > )
{
pro.SetValue(newObj, Convert.ChangeType(row[pro.Name], typeof(Boolean), null));
}
} }
}
list.Add(newObj);
}
return list;
} /// <summary>
/// reader转list
/// </summary>
/// <typeparam name="T">list类型</typeparam>
/// <param name="obj">model对象</param>
/// <param name="reader">数据源reader</param>
/// <returns>list </returns>
public static List<T> FillListByDataReader<T>(T obj ,IDataReader reader)
{
List<T> list = new List<T>(); Type t = obj.GetType(); PropertyInfo[] proList = t.GetProperties(); while(reader.Read())
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
stream.Position = ;
T newObj = (T)formatter.Deserialize(stream); foreach (PropertyInfo pro in proList)
{
Type tp = pro.PropertyType; DataFieldAttribute attr = pro.GetCustomAttributes().Count() > ? pro.GetCustomAttributes().First() as DataFieldAttribute : null; if (attr != null && attr.ColumnName == pro.Name)
{
if (ReaderExists(reader, pro.Name) && !string.IsNullOrEmpty(reader[pro.Name].ToString()))
{
if (tp.Name != "Nullable`1")
{
pro.SetValue(newObj, Convert.ChangeType(reader[pro.Name], tp));
}
else if (tp.FullName.IndexOf("System.DateTime") > )
{
pro.SetValue(newObj, Convert.ChangeType(reader[pro.Name], typeof(DateTime), null));
}
else if (tp.FullName.IndexOf("System.Int32") > )
{
pro.SetValue(newObj, Convert.ChangeType(reader[pro.Name], typeof(Int32), null));
}
else if (tp.FullName.IndexOf("System.Int64") > )
{
pro.SetValue(newObj, Convert.ChangeType(reader[pro.Name], typeof(Int64), null));
}
else if (tp.FullName.IndexOf("System.Decimal") > )
{
pro.SetValue(newObj, Convert.ChangeType(reader[pro.Name], typeof(Decimal), null));
}
else if (tp.FullName.IndexOf("System.Boolean") > )
{
pro.SetValue(newObj, Convert.ChangeType(reader[pro.Name], typeof(Boolean), null));
}
}
}
}
list.Add(newObj);
} return list;
} /// <summary>
/// reader转model对象
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="obj">model对象</param>
/// <param name="reader">数据源reader</param>
/// <returns>model对象</returns>
public static T FillObjectByDataReader<T>(T obj, IDataReader reader)
{
Type t = obj.GetType(); PropertyInfo[] proList = t.GetProperties(); if (reader.Read())
{
foreach (PropertyInfo pro in proList)
{
Type tp = pro.PropertyType; DataFieldAttribute attr = pro.GetCustomAttributes().Count() > ? pro.GetCustomAttributes().First() as DataFieldAttribute : null; if (attr != null && attr.ColumnName == pro.Name)
{
if (ReaderExists(reader, pro.Name) && !string.IsNullOrEmpty(reader[pro.Name].ToString()))
{
if (tp.Name != "Nullable`1")
{
pro.SetValue(obj, Convert.ChangeType(reader[pro.Name], tp));
}
else if (tp.FullName.IndexOf("System.DateTime") > )
{
pro.SetValue(obj, Convert.ChangeType(reader[pro.Name], typeof(DateTime), null));
}
else if (tp.FullName.IndexOf("System.Int32") > )
{
pro.SetValue(obj, Convert.ChangeType(reader[pro.Name], typeof(Int32), null));
}
else if (tp.FullName.IndexOf("System.Int64") > )
{
pro.SetValue(obj, Convert.ChangeType(reader[pro.Name], typeof(Int64), null));
}
else if (tp.FullName.IndexOf("System.Decimal") > )
{
pro.SetValue(obj, Convert.ChangeType(reader[pro.Name], typeof(Decimal), null));
}
else if (tp.FullName.IndexOf("System.Boolean") > )
{
pro.SetValue(obj, Convert.ChangeType(reader[pro.Name], typeof(Boolean), null));
}
}
}
}
} return obj;
} /// <summary>
/// row转model对象
/// </summary>
/// <typeparam name="T">model类型</typeparam>
/// <param name="obj">model对象</param>
/// <param name="row">数据源row</param>
/// <returns>model对象</returns>
public static T FillObjectByDataTable<T>(T obj, DataRow row)
{
Type t = obj.GetType(); PropertyInfo[] proList = t.GetProperties(); foreach (PropertyInfo pro in proList)
{
Type tp = pro.PropertyType; DataFieldAttribute attr = pro.GetCustomAttributes().Count() > ? pro.GetCustomAttributes().First() as DataFieldAttribute : null; if (attr != null && attr.ColumnName == pro.Name)
{
if (!string.IsNullOrEmpty(row[pro.Name].ToString()))
{
if (tp.Name != "Nullable`1")
{
pro.SetValue(obj, Convert.ChangeType(row[pro.Name], tp, null));
}
if (tp.Name != "Nullable`1")
{
pro.SetValue(obj, Convert.ChangeType(row[pro.Name], tp));
}
else if (tp.FullName.IndexOf("System.DateTime") > )
{
pro.SetValue(obj, Convert.ChangeType(row[pro.Name], typeof(DateTime), null));
}
else if (tp.FullName.IndexOf("System.Int32") > )
{
pro.SetValue(obj, Convert.ChangeType(row[pro.Name], typeof(Int32), null));
}
else if (tp.FullName.IndexOf("System.Int64") > )
{
pro.SetValue(obj, Convert.ChangeType(row[pro.Name], typeof(Int64), null));
}
else if (tp.FullName.IndexOf("System.Decimal") > )
{
pro.SetValue(obj, Convert.ChangeType(row[pro.Name], typeof(Decimal), null));
}
else if (tp.FullName.IndexOf("System.Boolean") > )
{
pro.SetValue(obj, Convert.ChangeType(row[pro.Name], typeof(Boolean), null));
}
} }
} return obj;
} /// <summary>
/// list转table
/// </summary>
/// <typeparam name="T">list类型</typeparam>
/// <param name="list">数据源list</param>
/// <param name="table">table</param>
/// <returns>table</returns>
public static DataTable FillDataTableByObject<T>(List<T> list , DataTable table)
{
if (list.Count > )
{
Type type = list[].GetType(); PropertyInfo[] properties = type.GetProperties(); DataColumnCollection dcc = table.Columns; foreach (var obj in list)
{
DataRow row = table.NewRow();
foreach (PropertyInfo p in properties)
{
if (dcc.Contains(p.Name.ToString()))
{
row[p.Name] = p.GetValue(obj);
}
}
table.Rows.Add(row);
}
}
return table;
} /// <summary>
/// 验证reader是否存在某列
/// </summary>
/// <param name="reader"></param>
/// <param name="columnName"></param>
/// <returns></returns>
private static bool ReaderExists(IDataReader reader,string columnName)
{
int count = reader.FieldCount;
for(int i = ; i < count; i++)
{
if(reader.GetName(i).Equals(columnName))
{
return true;
}
}
return false;
} }

利用反射把查询到的Table、Reader转换成List、Model的更多相关文章

  1. C#中利用LINQ to XML与反射把任意类型的泛型集合转换成XML格式字符串

    在工作中,如果需要跟XML打交道,难免会遇到需要把一个类型集合转换成XML格式的情况.之前的方法比较笨拙,需要给不同的类型,各自写一个转换的函数.但是后来接触反射后,就知道可以利用反射去读取一个类型的 ...

  2. android 按照拼音模糊查询中如何把字符转换成拼音

    http://files.cnblogs.com/liaolandemengxiang/%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9.rar 首先转换成的 ...

  3. 利用反射,泛型,静态方法快速获取表单值到Model

    在项目中经常需要处理表单,给model赋值,很烦人的一些重复代码.如下边的代码: News news = new News(); news.Id = int.Parse(Request.Form[&q ...

  4. SpringMVC分页查询无法直接将对象转换成json的解决办法(报org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type:错)

    在用ajax获得分页数据时,无法将获取的值赋值给input标签,在修改用户信息时不显示用户已经注册的信息,百度可知 springmvc处理分页数据返回的对象时,无法直接将对象转换成json,会报org ...

  5. python3.6 + selenium2.53.1 查询数据库并将返回的内容中每一行的内容转换成class对象

    环境: win10 python3.6 selenium2.53.1 准备工作:先安装pymysql python2.x链接数据库使用MySQLdb,而python3.x链接数据库使用pymysql ...

  6. 利用反射跟自定义注解拼接实体对象的查询SQL

    前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...

  7. <五>JDBC_利用反射及JDBC元数据编写通用的查询方法

    此类针对javaBean类写了一个通用的查询方法,List<javaBean> 通用查询更新中...:通过学习,深刻体会到学会反射就等于掌握了java基础的半壁江山! 一.使用JDBC驱动 ...

  8. 利用反射及jdbc元数据实现通用的查询方法

    ---------------------------------------------------------------------------------------------------- ...

  9. JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 * 可以由Connection得到 */ 具体的应用代码: @Te ...

随机推荐

  1. 剪花布条 --HDOJ 2087

    剪花布条 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. EXT 组件一些属性与方法(Tree)

    1.Ext.tree.TreePanel 主要配置项: root:树的根节点. rootVisible:是否显示根节点,默认为true. useArrows:是否在树中使用Vista样式箭头,默认为f ...

  3. 在Apache上部署Django

    跟php类似,要想使Apache能够处理python脚本(实际上Apache是不能处理脚本的,只是利用别的扩展模块处理相应脚本),就要给Apache安装相应的扩展模块. Apache起初的python ...

  4. Linux内核学习笔记1——系统调用原理【转】

    1什么是系统调用 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口.用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文 ...

  5. JavaScript高级程序设计54.pdf

    过滤输入 对于一些浏览器,可以使用正则表达式里的text()测试用户按下的按键,Firefox和safari(3.1版本之前)会对向上向下.退格键和删除键触发keypress事件,在Firefox中, ...

  6. WCF、.Net Remoting、Web Service概念及区别

    此文章主要参考http://www.cnblogs.com/weiweibtm/archive/2013/06/21/3148583.html 参考书籍<WCF全面解析上册>.<WC ...

  7. [LeetCode] Decode Ways 解题思路

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  8. c语言的label后面不能直接跟变量申明

    ; goto JUMP; printf("x is : %d\n",x); JUMP: ; <=== 错误,lable后面不能申明变量,只能是表达式语句(statement) ...

  9. Yii2 自动更新时间created_at updated_at

    创建model之后,新建一条记录,结果设计的表中created_at 字段 updated_at 字段 都是datetime 类型的,却不能自动插入当前时间.查看了资料,解决如下: 1.在class ...

  10. CAS协议 - CAS URIs

    http://desert3.iteye.com/blog/1703449 2.CAS URIs:  CAS是一个基于HTTP的协议,这就要求其每一个组成部分可以通过特定的URIs访问到.所有相关的U ...