首页新闻找找看学习计划

关于泛型集合与DataTable互转的问题

0
[已解决问题] 解决于 2017-05-11 08:45

泛型集合与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无效

MSky的主页 MSky | 菜鸟二级 | 园豆:436
提问于:2017-05-10 15:48
< >
分享
最佳答案
0

因为你在propertyinfo.setvalue时装箱了,你给一个临时对象set了value,而你可怜的实例就直接被add到list中去了。

所以你要么开始就装箱,到最后add的时候再拆箱就可以了。

ps下你那个propertyinfo.setvalue不是这样用的,你再怎么的也要changetype下吧,谁给你保证datatable中的dbtype和你代码的type能映射上?这还不说有些无法映射的,比如Guid等。

奖励园豆:5
Daniel Cai | 专家六级 |园豆:10374 | 2017-05-10 18:52

 映射还好,实体类跟数据库是对应的,除了枚举做了转换,应该是您说的装箱拆箱问题,这里比较薄弱,只知道表面的东西,再去看看资料

MSky | 园豆:436 (菜鸟二级) | 2017-05-11 08:44

 的确是这样,先把t装箱obj,在下面给objsetvalue,然后add的时候拆成T,通过了,还是基础知识不扎实,感谢指教

MSky | 园豆:436 (菜鸟二级) | 2017-05-11 09:02
其他回答(1)
0
 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.

~扎克伯格 | 园豆:1799 (小虾三级) | 2017-05-10 15:57

 转Class没问题,问题是T如果是Struct结构的话,有问题,我就想知道为什么不能用结构

支持(0) 反对(0) MSky | 园豆:436 (菜鸟二级) | 2017-05-10 16:08

@MSky: 因为结构是值类型 ,class是引用类型 

支持(1) 反对(0) ~扎克伯格 | 园豆:1799 (小虾三级) | 2017-05-10 16:13

@~扎克伯格: 这个我知道,只是为什么值类型就不可以呢

支持(0) 反对(0) MSky | 园豆:436 (菜鸟二级) | 2017-05-10 17:40

@MSky: where T : new()原因应该在这里

支持(0) 反对(0) Bluto | 园豆:317 (菜鸟二级) | 2017-05-10 18:21

@MSky: 还有值类型和引用类型的区别

支持(0) 反对(0) Bluto | 园豆:317 (菜鸟二级) | 2017-05-10 18:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册