一、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);

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

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

    介绍:List/IEnumerable转换到DataTable/DataView,以及DataTable转换到List 正文: 一.List<T>/IEnumerable转换到DataTa ...

  2. C# DataTable 和List之间相互转换的方法(转载)

    来源:https://www.cnblogs.com/shiyh/p/7478241.html 一.List<T>/IEnumerable转换到DataTable/DataView 方法一 ...

  3. win32内核程序中进程的pid,handle,eprocess之间相互转换的方法

    很有用,收下以后方便查询. 原贴地址:http://bbs.pediy.com/showthread.php?t=119193 在win32内核程序开发中,我们常常需要取得某进程的pid或句柄,或者需 ...

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

    1.List转换成为数组:返回数组的运行时类型.如果列表能放入指定的数组.否则,将根据指定数组.如果指定的数组的元素比列表的多),那么会将存储列表元素的数组. 返回:包含列表元素的list.add(& ...

  5. DOS和UNIX文本文件之间相互转换的方法

    在Unix/Linux下可以使用file命令查看文件类型,如下: file dosfile.txt 使用dos2unix 一般Linux发行版中都带有这个小工具,只能把DOS转换为UNIX文件,命令如 ...

  6. json对象与javaBean,String字符创之间相互转换的方法

    原创:转载请注明出处 package com.allcam.system.utils; import com.fasterxml.jackson.databind.ObjectMapper; publ ...

  7. protobuf与json相互转换的方法

    google的protobuf对象转json,不能直接使用FastJson之类的工具进行转换,原因是protobuf生成对象的get方法,返回的类型有byte[],而只有String类型可以作为jso ...

  8. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  9. IRandomAccessStream, IBuffer, Stream, byte[] 之间相互转换

    /* * 用于实现 IRandomAccessStream, IBuffer, Stream, byte[] 之间相互转换的帮助类 */ using System;using System.IO;us ...

随机推荐

  1. signtool

    https://msdn.microsoft.com/en-us/library/8s9b9yaz(v=vs.110).aspx C:\Users\Administrator\.nuget\packa ...

  2. (二)Kafka动态增加Topic的副本(Replication)

    (二)Kafka动态增加Topic的副本(Replication) 1. 查看topic的原来的副本分布 [hadoop@sdf-nimbus-perf ~]$ le-kafka-topics.sh ...

  3. [php] php图表显示

    使用jpgragh绘制php图表, 下载地址http://jpgraph.net/download/ 1> 服务器环境centos6.5, php5.0. 2> linux环境下需要配置j ...

  4. mysql exists 和 in的效率比较

    这条语句适用于a表比b表大的情况 select * from ecs_goods a where cat_id in(select cat_id from ecs_category b); 这条语句适 ...

  5. PHP的autoload机制的实现解析

    在使用PHP的OO模式开发系统时,通常大家习惯上将每个类的实现都存放在一个单独的文件里,这样会很容易实现对类进行复用,同时将来维护时也很便利 一.autoload机制概述 在使用PHP的OO模式开发系 ...

  6. 客户端判断是否为IE9以上版本

    function detectBrowser() { var browser = navigator.appName if(navigator.userAgent.indexOf("MSIE ...

  7. git ignore 添加忽略文件不生效解决办法

    在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中 .gitignore 文件的方法(如无,则需自己手工建立此文件).这个文件每一行保存了一个匹配的规则例如: /targ ...

  8. Makefile-入门与进阶【转】

    from:here 一.入门 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的 ...

  9. linux进程编程:子进程创建及执行函数简介

    linux进程编程:子进程创建及执行函数简介 子进程创建及执行函数有三个: (1)fork();(2)exec();(3)system();    下面分别做详细介绍.(1)fork()    函数定 ...

  10. Linux中关于安装包的分析。——Arvin

    初接解LINUX的,同样都是for linux,但rpm.tar.gz.deb包还是有很大区别的,这种区别可使安装过程进行不下去.那我们应该下载什么格式的包呢? rpm包-在红帽LINUX.SUSE. ...