泛型集合与DataTable互转进行互转,如果泛型集合为类,则可以转换,如果泛型集和为结构,为什么
PropertyInfo.SetValue(...)
是无法给值的呢,并且什么错也不报,贴一下转换的代码
/// <summary> /// DataTable转换成泛型集合 /// </summary> /// <typeparam name="T">泛型集合类型</typeparam> /// <param name="dt">DataTable</param> /// <returns>以实体类为元素的泛型集合</returns> public static IList<T> DataTableConvertToListGenuric<T>(DataTable dt) where T : new() { try { // 定义集合 List<T> ts = 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) pi.SetValue(t, value, null);---这里给t值失败,但是不报错,value有值 } } //对象添加到泛型集合中 ts.Add(t); } return ts; } catch (Exception ex) { throw ex; } }
如果传进来的T是class,一切正常,如果T是Struct,则setValue无效
因为你在propertyinfo.setvalue时装箱了,你给一个临时对象set了value,而你可怜的实例就直接被add到list中去了。
所以你要么开始就装箱,到最后add的时候再拆箱就可以了。
ps下你那个propertyinfo.setvalue不是这样用的,你再怎么的也要changetype下吧,谁给你保证datatable中的dbtype和你代码的type能映射上?这还不说有些无法映射的,比如Guid等。
映射还好,实体类跟数据库是对应的,除了枚举做了转换,应该是您说的装箱拆箱问题,这里比较薄弱,只知道表面的东西,再去看看资料
的确是这样,先把t装箱obj,在下面给objsetvalue,然后add的时候拆成T,通过了,还是基础知识不扎实,感谢指教
1 DataTable dt = new DataTable(); 2 dt.Columns.Add("Name"); 3 dt.Columns.Add("Age"); 4 dt.Columns.Add("School"); 5 for (int i = 0; i < 10; i++) 6 { 7 var newRow = dt.NewRow(); 8 newRow["Name"] = "戴威" + i; 9 newRow["Age"] = 23 + i; 10 newRow["School"] = "清华大学"; 11 dt.Rows.Add(newRow); 12 } 13 14 var studentlist = AutoMapper.Mapper.DynamicMap<List<Student>>(dt.CreateDataReader()); 15 16 17 public class Student 18 { 19 public string Name { get; set; } 20 public int Age { get; set; } 21 public string School { get; set; } 22 }
DataTable转集合。可以自己再封装成DataTable转泛型 集合。
可以测试下这段code,记得在 project中添加AutoMapper程序集 。版本不要高于 4.0.
转Class没问题,问题是T如果是Struct结构的话,有问题,我就想知道为什么不能用结构
@MSky: 因为结构是值类型 ,class是引用类型
@~扎克伯格: 这个我知道,只是为什么值类型就不可以呢
@MSky: where T : new()原因应该在这里
@MSky: 还有值类型和引用类型的区别