zoukankan      html  css  js  c++  java
  • DataTable数据集转换为List非泛型以及泛型方式

    前言

    DataTable是断开式的数据集合,所以一旦从数据库获取,就会在内存中创建一个数据的副本,以便使用。由于在实际项目中,经常会将DataTable中的每行数据转换为Model,然后放到List集合中,所以,下面提供了转换的两种思路:非泛型转换思路和泛型转换思路。

    非泛型方式

    首先来说下非泛型转换,这种转换方式就是通过遍历DataTable,然后向Model中的相同字段中赋值即可。

     //使用Linq的ToList方法,非泛型
            public static List<Entity> ConvertTo(DataTable dt)
            {
                if (dt == null) return null;
                if (dt.Rows.Count <= 0) return null;
     
                List<Entity> list = new List<Entity>();
                list = (from DataRow dr in dt.Rows
                        select new Entity
                        {
                            PID = Int32.Parse(dr["PID"].ToString()),
                            PName = dr["PName"].ToString(),
                            PPass = dr["PPass"].ToString(),
                            PAddr = dr["PAddr"].ToString()
                        }).ToList();
                return list;
            }

    代码很简单,就是通过循环赋值而已。这里我用的Model测试类如下:

     
    namespace DataSetToEntity.Code
    {
        public class Entity
        {
            public int PID { get; set; }
     
            public string PName { get; set; }
     
            public string PPass { get; set; }
     
            public string PAddr { get; set; }
        }
    }

    泛型方式

    然后,由于非泛型的版本不具有通用性,所以这里我们准备用泛型版本来实现一下,由于泛型版本是不可预知Model中的属性结构的,所以这里我们需要引入反射来进行操作。

    //使用反射的泛型方法一
            public static List<T> ConvertTo<T>(DataTable dt) where T : new()
            {
                if (dt == null) return null;
                if (dt.Rows.Count <= 0) return null;
     
                List<T> list = new List<T>();
                try
                {
                    List<string> columnsName = new List<string>();  
                    foreach (DataColumn dataColumn in dt.Columns)
                    {
                        columnsName.Add(dataColumn.ColumnName);//得到所有的表头
                    }
                    list = dt.AsEnumerable().ToList().ConvertAll<T>(row => getObject<T>(row, columnsName));  //转换
                    return list;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
     
            public static T getObject<T>(DataRow row, List<string> columnsName) where T : new()
            {
                T obj = new T();
                try
                {
                    string columnname = "";
                    string value = "";
                    PropertyInfo[] Properties = typeof(T).GetProperties();
                    foreach (PropertyInfo objProperty in Properties)  //遍历T的属性
                    {
                        columnname = columnsName.Find(name => name.ToLower() == objProperty.Name.ToLower()); //寻找可以匹配的表头名称
                        if (!string.IsNullOrEmpty(columnname))
                        {
                            value = row[columnname].ToString();
                            if (!string.IsNullOrEmpty(value))
                            {
                                if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null) //存在匹配的表头
                                {
                                    value = row[columnname].ToString().Replace("$", "").Replace(",", ""); //从dataRow中提取数据
                                    objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null); //赋值操作
                                }
                                else
                                {
                                    value = row[columnname].ToString().Replace("%", ""); //存在匹配的表头
                                    objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(objProperty.PropertyType.ToString())), null);//赋值操作
                                }
                            }
                        }
                    }
                    return obj;
                }
                catch
                {
                    return obj;
                }
            }
     
    上面主要是通过反射获取T的属性名称,然后和DataRow中的表头相匹配,如果匹配的上,就赋值。下面是其简化版本:
     
    //使用反射的泛型方法二
            public static List<T> ConvertToEx<T>(DataTable dt) where T : new()
            {
                if (dt == null) return null;
                if (dt.Rows.Count <= 0) return null;
     
                List<T> list = new List<T>();
                Type type = typeof(T);
                PropertyInfo[] propertyInfos = type.GetProperties();  //获取泛型的属性
                List<DataColumn> listColumns = dt.Columns.Cast<DataColumn>().ToList();  //获取数据集的表头,以便于匹配
                T t;
                foreach (DataRow dr in dt.Rows)   
                {
                    t = new T();
                    foreach (PropertyInfo propertyInfo in propertyInfos)
                    {
                        try
                        {
                            DataColumn dColumn = listColumns.Find(name => name.ToString().ToUpper() == propertyInfo.Name.ToUpper());  //查看是否存在对应的列名
                            if (dColumn != null)
                                propertyInfo.SetValue(t, dr[propertyInfo.Name], null);  //赋值
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(ex.Message);
                        }
                    }
                    list.Add(t);
                }
                return list;
            }
     
    至于使用方式,很简单,直接利用下面的代码即可:
     List<Entity> list = CommonUtils.ConvertToEx<Entity>(dt);
  • 相关阅读:
    mac下配置adb环境变量
    Flutter——多行文字展开收起
    sourceTree报错:Updates were rejected because the tag already exists in the remote.
    股市赚钱就是这么简单
    鸿蒙手机版JNI实战(JNI开发、SO库生成、SO库使用)
    Mybatis、Mybatis Generator、Mybatis-Plus、Mybatis Plus Generator
    鸿蒙运行报错:Failure[INSTALL_PARSE_FAILED_USESDK_ERROR] Error while Deploying HAP
    MAC 下Android ROM 提取文件
    IDAPython 插件开发
    Android ollvm 集成
  • 原文地址:https://www.cnblogs.com/scy251147/p/3364316.html
Copyright © 2011-2022 走看看