转 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);
转 C# DataTable 和List之间相互转换的方法的更多相关文章
- C# DataTable 和List之间相互转换的方法
介绍:List/IEnumerable转换到DataTable/DataView,以及DataTable转换到List 正文: 一.List<T>/IEnumerable转换到DataTa ...
- C# DataTable 和List之间相互转换的方法(转载)
来源:https://www.cnblogs.com/shiyh/p/7478241.html 一.List<T>/IEnumerable转换到DataTable/DataView 方法一 ...
- win32内核程序中进程的pid,handle,eprocess之间相互转换的方法
很有用,收下以后方便查询. 原贴地址:http://bbs.pediy.com/showthread.php?t=119193 在win32内核程序开发中,我们常常需要取得某进程的pid或句柄,或者需 ...
- 关于数组和List之间相互转换的方法
1.List转换成为数组:返回数组的运行时类型.如果列表能放入指定的数组.否则,将根据指定数组.如果指定的数组的元素比列表的多),那么会将存储列表元素的数组. 返回:包含列表元素的list.add(& ...
- DOS和UNIX文本文件之间相互转换的方法
在Unix/Linux下可以使用file命令查看文件类型,如下: file dosfile.txt 使用dos2unix 一般Linux发行版中都带有这个小工具,只能把DOS转换为UNIX文件,命令如 ...
- json对象与javaBean,String字符创之间相互转换的方法
原创:转载请注明出处 package com.allcam.system.utils; import com.fasterxml.jackson.databind.ObjectMapper; publ ...
- protobuf与json相互转换的方法
google的protobuf对象转json,不能直接使用FastJson之类的工具进行转换,原因是protobuf生成对象的get方法,返回的类型有byte[],而只有String类型可以作为jso ...
- 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换
路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...
- IRandomAccessStream, IBuffer, Stream, byte[] 之间相互转换
/* * 用于实现 IRandomAccessStream, IBuffer, Stream, byte[] 之间相互转换的帮助类 */ using System;using System.IO;us ...
随机推荐
- RPM安装rabbitMQ
系统使用的是centos 7 - minimal 建立用户和组: # groupadd rabbitmq # useradd rabbitmq -g rabbitmq 在安装rabbitMQ之前需要先 ...
- python走起之第四话
本节大纲: 一:双层装饰器:一个函数可以被多层装饰器进行装饰,函数渲染(编译)从下到上,函数执行从上到下.如下程序: 1 #!/usr/bin/env python 2 #-*-coding:utf- ...
- mongoDB 数据导出与导入
一.导出 命令格式:在mongodb/bin目录下 mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 -f 字段 -q 条件导出 --csv ...
- Java文件操作与输入输出流
文件操作 package ch15; import java.io.*; /** * Created by Jiqing on 2016/12/28. */ public class FileTest ...
- vs 2005 使用 boost regex
第一步: Boost 入门及其VS2005下编译boost库 boost.regex库安装指南 深入浅出之正则表达式(一) C++中三种正则表达式比较(C regex,C ++regex,boo ...
- Android之源码之模块编译和调试
Android之源码之模块编译调试 (一) 进行源码模块修改进行编译的调试 1.首先是从git或者svn上拉一套完整的工程下来,然后全编一下,一般这个时间比较长,大概会得2,3个小时左右, 2,编译成 ...
- MPICH3 配置安装问题列表
问题列表 1: configure: error: F90 and F90FLAGS are replaced by FC and FCFLAGS respectively in this confi ...
- NodeJS学习笔记 - Express4.x路由操作
一.为Express添加about路由 1.新建js文件,about.js 2.打开about.js,并输入以下代码: var express=require('express'); var rout ...
- 常用js,css文件统一加载方法,并在加载之后调用回调函数
原创内容,转载请注明出处! 为了方便资源管理和提升工作效率,常用的js和css文件的加载应该放在一个统一文件里面完成,也方便后续的资源维护.所以我用js写了以下方法,存放在“sourceControl ...
- HTML5的 2D SVG和SVG DOM的学习笔记(2)---SVG动画
SVG支持动画.可以通过以下几种方法获得动画效果: 使用SVG动画元素.SVG可以描述随时间变化的图形对象,使用不同的动画元素可以定义运动路径,淡入淡出效果和对象的膨胀.收缩.旋转和变换颜色. 使用S ...