DataTable 和List之间相互转换的方法

一、List<T>/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<T>对象遇到问题:类型“System.Int64”的对象无法转换为类型“System.Int32”

2017年09月03日 15:26:45

阅读数:1028

前言:

用三层开发的时候,D层经常会用到把DataTable对象转换为List对象的问题,一般情况下我们都会用到一个TableToList()方法,之前都是照着网上敲得,完了大致看一下就开始用了,也没出什么问题,也就没有仔细研究,这次用这个方法转换的时候遇到了一个异常(如题),出来混迟早要还的,这次让我重新研究了一下这个方法。

方法思路:

简单了解一下TableToList()方法的思路。 
1. 初始化一个List对象,获取到T所有的属性, 
2. 初始化一个T对象 遍历所有属性, 
3. 如果DataTable中含有相应属性的值则为T对象赋值,如果没有对应的列则检查数据模型是否定义有误(属性名与列名比较时不区分大小写) 
4. 将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;
        }

总结

还是多一点了解比较好,知其然也要之前所以然,要不然出问题的时候找不到问题原因,更找不到解决方法。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值