zoukankan      html  css  js  c++  java
  • C# DataTable 和List之间相互转换的方法

    一、List<T>/IEnumerable转换到DataTable/DataView

    方法一:

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

    二、DataTable转换到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;    
    }

    方法二:

    把查询结果以DataTable返回很方便,但是在检索数据时又很麻烦,没有模型类型检索方便。   

    所以很多人都是按照以下方式做的:  

    // 获得查询结果  
    DataTable dt = DbHelper.ExecuteDataTable(...);  
    // 把DataTable转换为IList<UserInfo>  
    IList<UserInfo> users = ConvertToUserInfo(dt);  

     问题:如果此系统有几十上百个模型,那不是每个模型中都要写个把DataTable转换为此模型的方法吗?  

    解决:能不能写个通用类,可以把DataTable转换为任何模型,呵呵,这就需要利用反射和泛型了  

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

    使用方式:  

    // 获得查询结果  
    DataTable dt = DbHelper.ExecuteDataTable(...);  
    // 把DataTable转换为IList<UserInfo>  
    IList<UserInfo> users = ModelConvertHelper<UserInfo>.ConvertToModel(dt);
  • 相关阅读:
    Discuz X 2.5 点点(伪静态)
    jq 、xml 省市级联动
    php memcache 初级使用(2)
    关于windows虚拟内存管理的页目录自映射
    SharePoint 2010 网络上的开发经验和资源
    SharePoint 2010 Reporting Services 报表服务器正在内置 NT AUTHORITY\SYSTEM 账户下运行 解决方法
    SharePoint 2010 Reporting Services 报表服务器无法解密用于访问报表服务器数据库中的敏感数据或加密数据的对称密钥 解决方法
    Active Directory Rights Management Services (AD RMS)无法检索证书层次结构。 解决方法
    SharePoint 2010 Reporting Services 报表服务器实例没有正确配置 解决方法
    SharePoint 2010 页面引用 Reporting Services 展现 List 报表
  • 原文地址:https://www.cnblogs.com/Echo529/p/6382653.html
Copyright © 2011-2022 走看看