zoukankan      html  css  js  c++  java
  • C#中DataTable转化为List<T>解析

        在.net项目中使用到DataTable和List<T>集合的地方较多, 泛型的好处: 它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值类型进行装箱和拆箱,或对引用类型进行。当涉及到两者之间的转换时,就显得有些较为繁琐。这个其中的问题主要在两者的存储方式,DataTable的存储方式采用一种二维表的方式进行数据的存储操作,DataTable表示内存中数据的一个表。在List集合中,List的本质就是一个数组,则采用一种线性结构对数据进行存储。

       在转换过程中,主要的问题在于不同类型的处理上,主要分为值类型和引用类型两大类。

           C#中值类型总是含有相应该类型的一个值,指类型包含:简单类型(Simple types ),结构类型(struct types),枚举类型(Enumeration types)。

           简单类型包含:整型,布尔型,字符型 (整型的一种特殊情况),浮点型,小数型。

           整型包含: sbyte 、byte、 short、 ushort、 int、 uint、 long、 ulong 和 char。

           引用类型:引用类型不存储它们所代表的实际数据,但它们存储实际数据的引用。主要包含:对象类型,类类 型,接口,代表元,字符串类型,数组。

        现提供转换的代码,仅供参考:

    1.类型枚举:

           /// <summary>
            /// 类型枚举
            /// </summary>
            private enum ModelType
            {
                //值类型
                Struct,
                Enum,
                //引用类型
                String,
                Object,
                Else
            }
    
    
            private static ModelType GetModelType(Type modelType)
            {
                //值类型
                if (modelType.IsEnum)
                {
                    return ModelType.Enum;
                }
                //值类型
                if (modelType.IsValueType)
                {
                    return ModelType.Struct;
                }
                //引用类型 特殊类型处理
                if (modelType == typeof(string))
                {
                    return ModelType.String;
                }
                //引用类型 特殊类型处理
                return modelType == typeof(object) ? ModelType.Object : ModelType.Else;
            }

    2.具体的转换操作方法:

            /// <summary>
            /// datatable转换为List<T>集合
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="table"></param>
            /// <returns></returns>
            public static List<T> DataTableToList<T>(DataTable table)
            {
                var list = new List<T>();
                foreach (DataRow item in table.Rows)
                {
                    list.Add(DataRowToModel<T>(item));
                }
                return list;
            }
    
            public static T DataRowToModel<T>(DataRow row)
            {
                T model;
                var type = typeof(T);
                var modelType = GetModelType(type);
                switch (modelType)
                {
                    //值类型
                    case ModelType.Struct:
                        {
                            model = default(T);
                            if (row[0] != null)
                                model = (T)row[0];
                        }
                        break;
                    //值类型
                    case ModelType.Enum:
                        {
                            model = default(T);
                            if (row[0] != null)
                            {
                                var fiType = row[0].GetType();
                                if (fiType == typeof(int))
                                {
                                    model = (T)row[0];
                                }
                                else if (fiType == typeof(string))
                                {
                                    model = (T)Enum.Parse(typeof(T), row[0].ToString());
                                }
                            }
                        }
                        break;
                    //引用类型 c#对string也当做值类型处理
                    case ModelType.String:
                        {
                            model = default(T);
                            if (row[0] != null)
                                model = (T)row[0];
                        }
                        break;
                    //引用类型 直接返回第一行第一列的值
                    case ModelType.Object:
                        {
                            model = default(T);
                            if (row[0] != null)
                                model = (T)row[0];
                        }
                        break;
                    //引用类型
                    case ModelType.Else:
                        {
                            //引用类型 必须对泛型实例化
                            model = Activator.CreateInstance<T>();
                            //获取model中的属性
                            var modelPropertyInfos = type.GetProperties();
                            //遍历model每一个属性并赋值DataRow对应的列
                            foreach (var pi in modelPropertyInfos)
                            {
                                //获取属性名称
                                var name = pi.Name;
                                if (!row.Table.Columns.Contains(name) || row[name] == null) continue;
                                var piType = GetModelType(pi.PropertyType);
                                switch (piType)
                                {
                                    case ModelType.Struct:
                                        {
                                            var value = Convert.ChangeType(row[name], pi.PropertyType);
                                            pi.SetValue(model, value, null);
                                        }
                                        break;
                                    case ModelType.Enum:
                                        {
                                            var fiType = row[0].GetType();
                                            if (fiType == typeof(int))
                                            {
                                                pi.SetValue(model, row[name], null);
                                            }
                                            else if (fiType == typeof(string))
                                            {
                                                var value = (T)Enum.Parse(typeof(T), row[name].ToString());
                                                if (value != null)
                                                    pi.SetValue(model, value, null);
                                            }
                                        }
                                        break;
                                    case ModelType.String:
                                        {
                                            var value = Convert.ChangeType(row[name], pi.PropertyType);
                                            pi.SetValue(model, value, null);
                                        }
                                        break;
                                    case ModelType.Object:
                                        {
                                            pi.SetValue(model, row[name], null);
                                        }
                                        break;
                                    case ModelType.Else:
                                        throw new Exception("不支持该类型转换");
                                    default:
                                        throw new Exception("未知类型");
                                }
                            }
                        }
                        break;
                    default:
                        model = default(T);
                        break;
                }
                return model;
            }

        以上的操作中,对不同类型有对应的处理方式。

  • 相关阅读:
    java多线程的基本介绍
    Fragment基本介绍
    TypedValue.applyDimension的使用
    获取当前进程名并判断是否是主进程
    Bitmap类、BitmapFactory及BitmapFactory类中的常用方法
    Android 动态改变图片的颜色值
    Glide4.0使用
    Android在一个app中启动另一个App
    使用Recyclerview实现图片水平自动循环滚动
    Java变量的修饰符
  • 原文地址:https://www.cnblogs.com/pengze0902/p/5973862.html
Copyright © 2011-2022 走看看