一、List/IEnumerable转换到DataTable/DataView
方法一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /// <summary> /// Convert a List{T} to a DataTable. /// </summary> private DataTable ToDataTable<T>(List<T> items) { var tb = new DataTable( typeof (T).Name); PropertyInfo[] props = typeof (T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo prop in props) { Type t = GetCoreType(prop.PropertyType); tb.Columns.Add(prop.Name, t); } foreach (T item in items) { var values = new object [props.Length]; for ( int i = 0; i < props.Length; i++) { values[i] = props[i].GetValue(item, null ); } tb.Rows.Add(values); } return tb; } /// <summary> /// Determine of specified type is nullable /// </summary> public static bool IsNullable(Type t) { return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof (Nullable<>)); } /// <summary> /// Return underlying type if type is Nullable otherwise return the type /// </summary> public static Type GetCoreType(Type t) { if (t != null && IsNullable(t)) { if (!t.IsValueType) { return t; } else { return Nullable.GetUnderlyingType(t); } } else { return t; } } |
方法二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public static DataTable ToDataTable<T>(IEnumerable<T> collection) { var props = typeof (T).GetProperties(); var dt = new DataTable(); dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name, p.PropertyType)).ToArray()); if (collection.Count() > 0) { for ( int i = 0; i < collection.Count(); i++) { ArrayList tempList = new ArrayList(); foreach (PropertyInfo pi in props) { object obj = pi.GetValue(collection.ElementAt(i), null ); tempList.Add(obj); } object [] array = tempList.ToArray(); dt.LoadDataRow(array, true ); } } return dt; } |
二、DataTable转换到List
方法一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | public static IList<T> ConvertTo<T>(DataTable table) { if (table == null ) { return null ; } List<DataRow> rows = new List<DataRow>(); foreach (DataRow row in table.Rows) { rows.Add(row); } return ConvertTo<T>(rows); } public static IList<T> ConvertTo<T>(IList<DataRow> rows) { IList<T> list = null ; if (rows != null ) { list = new List<T>(); foreach (DataRow row in rows) { T item = CreateItem<T>(row); list.Add(item); } } return list; } public static T CreateItem<T>(DataRow row) { T obj = default (T); if (row != null ) { obj = Activator.CreateInstance<T>(); foreach (DataColumn column in row.Table.Columns) { PropertyInfo prop = obj.GetType().GetProperty(column.ColumnName); try { object value = row[column.ColumnName]; prop.SetValue(obj, value, null ); } catch { //You can log something here //throw; } } } return obj; } |
方法二:
把查询结果以DataTable返回很方便,但是在检索数据时又很麻烦,没有模型类型检索方便。
所以很多人都是按照以下方式做的:
1 2 3 4 | // 获得查询结果 DataTable dt = DbHelper.ExecuteDataTable(…); // 把DataTable转换为IList<UserInfo> IList<UserInfo> users = ConvertToUserInfo(dt); |
问题:如果此系统有几十上百个模型,那不是每个模型中都要写个把DataTable转换为此模型的方法吗?
解决:能不能写个通用类,可以把DataTable转换为任何模型,呵呵,这就需要利用反射和泛型了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Reflection; namespace NCL.Data { /// <summary> /// 实体转换辅助类 /// </summary> public class ModelConvertHelper<T> where T : new () { public static IList<T> ConvertToModel(DataTable dt) { // 定义集合 IList<T> ts = new List<T>(); // 获得此模型的类型 Type type = typeof (T); string tempName = “” ; foreach (DataRow dr in dt.Rows) { T t = new T(); // 获得此模型的公共属性 PropertyInfo[] propertys = t.GetType().GetProperties(); foreach (PropertyInfo pi in propertys) { tempName = pi.Name; // 检查DataTable是否包含此列 if (dt.Columns.Contains(tempName)) { // 判断此属性是否有Setter if (!pi.CanWrite) continue ; object value = dr[tempName]; if (value != DBNull.Value) pi.SetValue(t, value, null ); } } ts.Add(t); } return ts; } } } |
使用方式:
1 2 3 4 | // 获得查询结果 DataTable dt = DbHelper.ExecuteDataTable(…); // 把DataTable转换为IList<UserInfo> IList<UserInfo> users = ModelConvertHelper<UserInfo>.ConvertToModel(dt); |
原文地址:https://www.cnblogs.com/shiyh/p/7478241.html
将DataTable转换为List对象遇到问题:类型“System.Int64”的对象无法转换为类型“System.Int32”
2017年09月03日 15:26:45
阅读数:1028
前言:
用三层开发的时候,D层经常会用到把DataTable对象转换为List对象的问题,一般情况下我们都会用到一个TableToList()方法,之前都是照着网上敲得,完了大致看一下就开始用了,也没出什么问题,也就没有仔细研究,这次用这个方法转换的时候遇到了一个异常(如题),出来混迟早要还的,这次让我重新研究了一下这个方法。
方法思路:
简单了解一下TableToList()方法的思路。
- 初始化一个List对象,获取到T所有的属性,
- 初始化一个T对象 遍历所有属性,
- 如果DataTable中含有相应属性的值则为T对象赋值,如果没有对应的列则检查数据模型是否定义有误(属性名与列名比较时不区分大小写)
- 将T对象添加到List对象中
遇到的问题

我也是很奇怪,我的plan_flag字段在前边明明传进去的就是int32的,到这里怎么成了int64不能转换成int32位了。
根据之前的思路和异常出现的地方,问题出在给对象的属性赋值这步。
因为转换时在DataTable里某个字段类型是Int32会有问题,报异常,所以我们可在赋值的时候加一个判断:
//加一重if判断,如果属性值是int32类型的,就进行一次强制转换
if(pi.GetMethod.ReturnParameter.ParameterType.Name == "Int32")
{
value = Convert.ToInt32(value);
}
pi.SetValue(t, value, null);
完整的方法
/// <summary>
/// DataTable转换为List
/// </summary>
/// <typeparam name="T">实体对象</typeparam>
/// <param name="dt">datatable表</param>
/// <returns>返回list集合</returns>
public List<T> TableToList<T>(DataTable dt) where T : new()
{
//定义集合
List<T> list = new List<T>();
//获得此模型的类型
Type type = typeof(T);
//定义一个临时变量
string tempName = string.Empty;
//遍历Datatable中所有的数据行
foreach (DataRow dr in dt.Rows)
{
T t = new T();
//获得此模型的公共属性
PropertyInfo[] propertys = t.GetType().GetProperties();
//遍历该对象的所有属性
foreach (PropertyInfo pi in propertys)
{
//将属性名称赋值给临时变量
tempName = pi.Name;
//检查DataTable是否包含此列(列名==对象的属性名)
if (dt.Columns.Contains(tempName))
{
//判断此属性是否有Setter
if (!pi.CanWrite) continue;//该属性不可写,直接跳出
//取值
object value = dr[tempName];
//如果非空,则赋给对象的属性
if (value != DBNull.Value)
{
//加一重if判断,如果属性值是int32类型的,就进行一次强制转换
if(pi.GetMethod.ReturnParameter .ParameterType.Name=="Int32")
{
value = Convert.ToInt32(value);
}
pi.SetValue(t, value, null);
}
}
}
//对象添加到泛型集合中
list.Add(t);
}
return list;
}
总结
还是多一点了解比较好,知其然也要之前所以然,要不然出问题的时候找不到问题原因,更找不到解决方法。
还没有评论,来说两句吧...