转 C# DataTable 和List之间相互转换的方法

一、List/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返回很方便,但是在检索数据时又很麻烦,没有模型类型检索方便。

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

1234 // 获得查询结果  
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);

时间: 2024-10-10 11:32:06

转 C# DataTable 和List之间相互转换的方法的相关文章

C# DataTable 和List之间相互转换的方法

一.List<T>/IEnumerable转换到DataTable/DataView private DataTable ToDataTable<T>(List<T> items) { var tb = new DataTable(typeof (T).Name); PropertyInfo[] props = typeof (T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (

关于数组和List之间相互转换的方法

1.List转换成为数组:返回数组的运行时类型.如果列表能放入指定的数组.否则,将根据指定数组.如果指定的数组的元素比列表的多),那么会将存储列表元素的数组. 返回:包含列表元素的list.add("2");final int size =  list.size();String[] arr = (String[])list.toArray(new String[size]); 2.为List.调用Arrays的asList方法.asListpublic static <T>

二进制数据和文件之间相互转换的方法

在网上寻找的方法,可以实现把数据库中的二进制数据转换成文件,也可以把本地的文件转成二进制的数据.二进制的图片数据可以用response对象直接输出给浏览器,比较方便~ 话不多说,代码送上! /// /// 文件转为 二进制/// /// 文件路径/// public static byte[] File2Bytes(string path){if (!System.IO.File.Exists(path)){return new byte[0];}FileInfo fi = new FileIn

C++ 中 int,char*,string,CString之间相互转换-整理

#include <string> //使用C++标准库的string类时 using namespace std; //同上 #include <sstream> #include <iostream> #include <stdlib.h> //要将string类和int类型直接转换最好有这些包含, //因为自己写一个转换函数比较方便,函数定义参考如下 string getstring ( const int n ) { std::stringstrea

XML和实体类之间相互转换(序列化和反序列化)

我们需要在XML与实体类,DataTable,List之间进行转换,下面是XmlUtil类,该类来自网络并稍加修改. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67

php中 xml json 数组 之间相互转换

php中 xml json  数组 之间相互转换 1 数组转json $result = array( 'status' =>$status, 'message'=>$message, 'data'=>$data, ); json_encode($result);

C# XML和实体类之间相互转换(序列化和反序列化)

我们需要在XML与实体类,DataTable,List之间进行转换,下面是XmlUtil类,该类来自网络并稍加修改. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using System.Xml; using System.Xml.Serialization; /// <summary> ///

HTML(DOM)与JavaScript嵌套数组之间相互转换

1. [代码][JavaScript]代码     /*<html><head>  <title>HTML RESTructure</title><style></style><script>*/// workDOM函数遍历目标元素或节点// 有两种模式://   1. `element`模式(默认)(包含所定义的元素项)//   2. `node`模式(包含文本节点在内的所有节点)function walkDOM(mod

c# XML和实体类之间相互转换(序列化和反序列化)[砖]

link: http://blog.okbase.net/haobao/archive/62.html by: 好饱 我们需要在XML与实体类,DataTable,List之间进行转换,下面是XmlUtil类,该类来自网络并稍加修改. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47