zoukankan      html  css  js  c++  java
  • DataTable和List之间互转

    参考https://www.cnblogs.com/shiyh/p/7478241.html

    Table to List 

    一、

    static public List<T> Tolist<T>(DataTable dt) where T : class, new()
            {
                Type t = typeof(T);
                PropertyInfo[] PropertyInfo = t.GetProperties();
                List<T> list = new List<T>();
    
                string typeName = string.Empty;
                foreach (DataRow item in dt.Rows)
                {
                    T obj = new T();
                    foreach (PropertyInfo s in PropertyInfo)
                    {
                        typeName = s.Name;
                        if (dt.Columns.Contains(typeName))
                        {
                            if (!s.CanWrite) continue;
    
                            object value = item[typeName];
                            if (value == DBNull.Value) continue;
    
                            if (s.PropertyType == typeof(string))
                            {
                                s.SetValue(obj, value.ToString(), null);
                            }
                            else
                            {
                                s.SetValue(obj, value, null);
                            }
                        }
                    }
                    list.Add(obj);
                }
                return list;
            }
    

    二、

    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;    
    }

    三、利用反射和泛型,创建实体转换辅助类

    调用;  IList<UserInfo> users = ModelConvertHelper<UserInfo>.ConvertToModel(dt);

    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):

            /// <summary>
            /// DateTable转为List
            /// </summary>
            /// <returns></returns>
            public static List<T> ToList<T>(this DataTable dt)
            {
                List<string> dataColumn = dt.Columns.Cast<DataColumn>().Select(c => c.ColumnName).ToList();
                PropertyInfo[] properties = typeof(T).GetProperties();
                string columnName = string.Empty;
                return dt.AsEnumerable().Select(row =>
                {
                    T t = Activator.CreateInstance<T>();
                    foreach (PropertyInfo p in properties)
                    {
                        columnName = p.Name;
                        if (dataColumn.Contains(columnName))
                        {
                            if (!p.CanWrite)
                                continue;
                            object value = row[columnName];
                            Type type = p.PropertyType;
                            if (value != DBNull.Value)
                                p.SetValue(t, Convert.ChangeType(value, type), null);
                        }
                    }
                    return t;
                }).ToList();
            }

    四、高性能的基于Emit的实现

    /// <summary>
    /// 把datatable转换为对象集合列表List<T>
    /// </summary>
        public class DataTableConvert
        {
            //把DataRow转换为对象的委托声明
            private delegate T Load<T>(DataRow dataRecord);
    
            //用于构造Emit的DataRow中获取字段的方法信息
            private static readonly MethodInfo getValueMethod = typeof(DataRow).GetMethod("get_Item", new Type[] { typeof(int) });
    
            //用于构造Emit的DataRow中判断是否为空行的方法信息
            private static readonly MethodInfo isDBNullMethod = typeof(DataRow).GetMethod("IsNull", new Type[] { typeof(int) });
    
            //使用字典存储实体的类型以及与之对应的Emit生成的转换方法
            private static Dictionary<Type, Delegate> rowMapMethods = new Dictionary<Type, Delegate>();
    
            public static List<T> ToList<T>(DataTable dt)
            {
                List<T> list = new List<T>();
                if (dt == null)
                    return list;
    
                //声明 委托Load<T>的一个实例rowMap
                Load<T> rowMap = null;
    
    
                //从rowMapMethods查找当前T类对应的转换方法,没有则使用Emit构造一个。
                if (!rowMapMethods.ContainsKey(typeof(T)))
                {
                    DynamicMethod method = new DynamicMethod("DynamicCreateEntity_" + typeof(T).Name, typeof(T), new Type[] { typeof(DataRow) }, typeof(T), true);
                    ILGenerator generator = method.GetILGenerator();
                    LocalBuilder result = generator.DeclareLocal(typeof(T));
                    generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
                    generator.Emit(OpCodes.Stloc, result);
    
                    for (int index = 0; index < dt.Columns.Count; index++)
                    {
                        PropertyInfo propertyInfo = typeof(T).GetProperty(dt.Columns[index].ColumnName);
                        Label endIfLabel = generator.DefineLabel();
                        if (propertyInfo != null && propertyInfo.GetSetMethod() != null)
                        {
                            generator.Emit(OpCodes.Ldarg_0);
                            generator.Emit(OpCodes.Ldc_I4, index);
                            generator.Emit(OpCodes.Callvirt, isDBNullMethod);
                            generator.Emit(OpCodes.Brtrue, endIfLabel);
                            generator.Emit(OpCodes.Ldloc, result);
                            generator.Emit(OpCodes.Ldarg_0);
                            generator.Emit(OpCodes.Ldc_I4, index);
                            generator.Emit(OpCodes.Callvirt, getValueMethod);
                            generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
                            generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
                            generator.MarkLabel(endIfLabel);
                        }
                    }
                    generator.Emit(OpCodes.Ldloc, result);
                    generator.Emit(OpCodes.Ret);
    
                    //构造完成以后传给rowMap
                    rowMap = (Load<T>)method.CreateDelegate(typeof(Load<T>));
                }
                else
                {
                    rowMap = (Load<T>)rowMapMethods[typeof(T)];
                }
    
                //遍历Datatable的rows集合,调用rowMap把DataRow转换为对象(T)
                foreach (DataRow info in dt.Rows)
                    list.Add(rowMap(info));
                return list;
    
            }
        }

    List To Tabel

    一、

    /// <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;
        }
    }

    二、

    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;
     }

    高性能的基于Emit实现的

  • 相关阅读:
    关于 TIdHttp
    DCEF3 相关资料
    WPF RichTextBox 控件常用方法和属性
    Delphi Data Type to C# Data Type
    获取 CPU 序列号
    Visual Studio 调用 Delphi DLL 会退出的解决方案
    IDHttp的基本用法(转)
    TChromeTabs 优化改进
    java与json转换
    js charAt()方法
  • 原文地址:https://www.cnblogs.com/wangdongying/p/12936798.html
Copyright © 2011-2022 走看看