目录

前言

想法

两者的区别

个人想法

完整代码

方式一

方式二

类型转换


前言

最近在捣鼓DataTable,弄到了类型转换,既然弄了,那就整个记录。有不足之处,请多多指教。我看了一下目前的转换方式基本上都大差不差,基本上都是通过反射来操作的。本文介绍的两种方式也都是利用反射来完成的。两种方式都写成的通用类,仅供参考。

想法两者的区别

  • DataTable 内存中的数据表 一个二维表
  • List泛型数组 这里面存放的是一个一个的被对象化的数据模型

个人想法

  • 其实也可以写一个类,把DataTable转换成List<Dictionary>(),但是并不太建议,我感觉也不太方便。
  • 我比较推荐利用反射来弄,相对通用。
  • 以下方法中的T为自己定义的类,其中的属性需要与数据库对应

完整代码

  • 方式一
// Licensed to the .NET Foundation under one or more agreements.// The .NET Foundation licenses this file to you under the MIT license.// See the LICENSE file in the project root for more information.using System;using System.Collections.Generic;using System.Data;using System.Reflection;namespace GCT.TestInterface{    public static class DataTableHelper    {        ///         /// DataTable转成List        ///         public static List<T> ToDataList<T>(this DataTable dt)        {            var list = new List();            //创建一个属性的列表,并赋值            var plist = new List(typeof(T).GetProperties());            if (dt == null || dt.Rows.Count == 0)            {                return null;            }            foreach (DataRow item in dt.Rows)            {                //实例化泛型对象                T s = Activator.CreateInstance();                //遍历dataTable中的列集合                for (int i = 0; i < dt.Columns.Count; i++)                {                    //获取属性和DataTable的列名称相同的属性(PropertyInfo)                    PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);                    //判断是否存在                    if (info != null)                    {                        try                        {                            //判断是否为空                            if (!Convert.IsDBNull(item[i]))                            {                                object v = null;                                //判断属性是否包含可空                                if (info.PropertyType.ToString().Contains("System.Nullable"))                                {                                    //类型转换                                    v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));                                }                                else                                {                                    //类型转换                                    v = Convert.ChangeType(item[i], info.PropertyType);                                }                                //赋值                                info.SetValue(s, v, null);                            }                        }                        catch (Exception ex)                        {                            throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);                        }                    }                }                list.Add(s);            }            return list;        }        ///         /// DataTable转成实体对象        ///         ///         ///         ///         public static T ToDataEntity<T>(this DataTable dt)        {            T s = Activator.CreateInstance();            if (dt == null || dt.Rows.Count == 0)            {                return default(T);            }            var plist = new List(typeof(T).GetProperties());            for (int i = 0; i 
p.Name == dt.Columns[i].ColumnName); if (info != null) { try { if (!Convert.IsDBNull(dt.Rows[0][i])) { object v = null; if (info.PropertyType.ToString().Contains("System.Nullable")) { v = Convert.ChangeType(dt.Rows[0][i], Nullable.GetUnderlyingType(info.PropertyType)); } else { v = Convert.ChangeType(dt.Rows[0][i], info.PropertyType); } info.SetValue(s, v, null); } } catch (Exception ex) { throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message); } } } return s; } /// /// List转成DataTable /// /// 实体类型 /// 实体集合 public static DataTable ToDataTable<T>(List entities) { //判断List的状态 if (entities == null || entities.Count == 0) { return null; } //新建一个DataTable var result = new DataTable(); //获取实体类型数据 var type = typeof(T); //遍历实体类型数据 foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { //获取属性类型 var propertyType = property.PropertyType; //判断是否存在,是否可为空 if (propertyType.IsGenericType && (propertyType.GetGenericTypeDefinition() == typeof(Nullable))) { propertyType = propertyType.GetGenericArguments()[0]; } //添加列 result.Columns.Add(property.Name, propertyType); } foreach (var entity in entities) { //创建一个具有相同架构的表格行 DataRow row = result.NewRow(); foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { //填充数据 row[property.Name] = property.GetValue(entity) ?? DBNull.Value; } //添加行 result.Rows.Add(row); } return result; } }}

  • 方式二
// Licensed to the .NET Foundation under one or more agreements.// The .NET Foundation licenses this file to you under the MIT license.// See the LICENSE file in the project root for more information.using System;using System.Collections.Generic;using System.Data;using System.Reflection;namespace GCT.TestInterface{    public static class DataTableHelper    {        ///         /// 利用反射将Datatable转换为List对象        ///         /// 集合        ///  datatable对象        ///         public static List<T> ToDataList<T>(this DataTable dt) where T : new()        {            //定义集合            List ts = new List();            //遍历dataTable中的数据行            foreach (DataRow dr in dt.Rows)            {                T t = new T();                //这里也有两种写法,可以先获取模型的属性数组,也先遍历再获取指定值的属性,看自己喜好采用                #region 获得此模型的公共属性                ////获得此模型的公共属性                PropertyInfo[] propertys = t.GetType().GetProperties();                //遍历该对象的所有属性                foreach (PropertyInfo pi in propertys)                {                    string tempName = pi.Name;                    //检查datatable是否包含此列(列名==对象的属性名)                    //判断此属性是否有setter,这个啥意思呢,就是我们的实体层的{get;set;}如果我们的实体有了set方法,就说明可以赋值!                    if (!dt.Columns.Contains(tempName) && !pi.CanWrite) continue;                    object value = dr[tempName];//取值                    if (value == DBNull.Value) continue;  //如果非空,则赋给对象的属性                    pi.SetValue(t, ConvertHelper.HackType(value, pi.PropertyType), null);                }                #endregion                #region 先遍历再获取指定的                //遍历dataTable列集合                foreach (var c in dt.Columns)                {                    //读取值                    object value = dr[c.ToString()];                    //判断是否存在                    if (value != DBNull.Value)                    {                        //获取指定值的属性                        var p = t.GetType().GetProperty(c.ToString());                        if (p != null)                        {                            //对象赋值                            p.SetValue(t, ConvertHelper.ChangeType(value, p.PropertyType), null);                        }                    }                }                #endregion                //对象添加到泛型集合中                ts.Add(t);            }            return ts;        }        ///         /// DataTable转成实体对象        ///         ///         ///         ///         ///         public static T ToDataEntity<T>(this DataTable dt) where T : new()        {            if (dt.Rows.Count > 1)            {                throw new Exception("");            }            //遍历行            foreach (DataRow dr in dt.Rows)            {                T t = new T();                //遍历列                foreach (var c in dt.Columns)                {                    //获取指定值                    object value = dr[c.ToString()];                    if (value != DBNull.Value)                    {                        //获取公共属性                        var p = t.GetType().GetProperty(c.ToString());                        if (p != null)                        {                            p.SetValue(t, ConvertHelper.ChangeType(value, p.PropertyType), null);                        }                    }                }                return t;            }            return default(T);        }    }}

  • 类型转换

用方式二有时候会报类型转换的错误,因此也提供了两种转换方式

    ///     /// 类型转换    ///     public static class ConvertHelper    {        #region 方式一        public static object HackType(object value, Type conversionType)        {            if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable)))            {                if (value == null)                    return null;                System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(conversionType);                conversionType = nullableConverter.UnderlyingType;            }            return Convert.ChangeType(value, conversionType);        }        #endregion 方式一        #region 方式二        public static object ChangeType(object obj, Type conversionType)        {            return ChangeType(obj, conversionType, System.Threading.Thread.CurrentThread.CurrentCulture);        }        public static object ChangeType(object obj, Type conversionType, IFormatProvider provider)        {            #region Nullable            Type nullableType = Nullable.GetUnderlyingType(conversionType);            if (nullableType != null)            {                if (obj == null)                {                    return null;                }                return Convert.ChangeType(obj, nullableType, provider);            }            #endregion Nullable            if (typeof(Enum).IsAssignableFrom(conversionType))            {                return Enum.Parse(conversionType, obj.ToString());            }            return Convert.ChangeType(obj, conversionType, provider);        }        #endregion 方式二    }