菜鸟一枚,入园已有两年三个月,这还是第一次写博客,请各位大神斧正。
这是我写的一个工具类,通常我们从数据库查询到一个 DataReader 或者是 一个 Table , 想要转换成 一个 list 或者是 一个model 的话 , 一般情况下是使用foreach 循环reader或是table的rows,然后在循环内创建个对象,通过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;
} }