在程序中,往往会遇到一些小情况,就是数据库取出来的时候为了方便直接将数据通过存储在DataSet或DataTable中,这样做的一个后果是在日后的的对数据进行”细“操作时,就发现它可能没有List<T>那么方便,而另外一些时候(比如使用SqlBulkCopy的时候)使用DataTable会比较方便。于是我们就会想写一个专门的它们之间的互操作来使我们在操作它们的时候变得不那么复杂。网上关于它们之间的互操作的解决方法蛮多。这里参考了下它们,结合自己实际应用,写了一个它们之间互操,代码如下:

public static class DataTableEntityInteroperate
{
/// <summary>
/// List<T> to DataTable
/// </summary>
/// <typeparam name="T">Entity</typeparam>
/// <param name="entities">Entities</param>
/// <returns>DataTable</returns>
internal static DataTable ToDataTable<T>(this List<T> entities) where T : class,new()
{
//IsNull return
if (null == entities || entities.Count == )
return null;
//Initial Columns
DataTable dt = new DataTable();
PropertyInfo[] pArray = typeof(T).GetProperties();
try
{
Array.ForEach<PropertyInfo>(pArray, p =>
{
dt.Columns.Add(p.Name);
}); entities.ForEach(t =>
{
//Initial Rows
DataRow dr=dt.NewRow();
int i = ;
Array.ForEach<PropertyInfo>(pArray, p =>
{
if (dt.Columns.Contains(p.Name))
dr[i] = p.GetValue(t); //Assigned to each column
});
i++;
dt.Rows.Add(dr);//备忘,测试不仔细。
});
return dt;
}
catch (Exception)
{ throw;
} } /// <summary>
/// DataTable to Entities
/// </summary>
/// <typeparam name="T">Entity</typeparam>
/// <param name="dt">DataTable</param>
/// <returns>List<T</returns>
internal static List<T> ToEntities<T>(this DataTable dt)/*必须来在于数据库来自于文件可能存在问题*/ where T : class,new()
{
//IsNullable
if (null == dt || dt.Rows.Count == )
return null;
//Initial Entities
List<T> entities = new List<T>();
try
{
foreach (DataRow row in dt.Rows)
{
PropertyInfo[] pArray = typeof(T).GetProperties();
T entity = new T();
Array.ForEach<PropertyInfo>(pArray, p =>
{
if(row[p.Name]!=DBNull.Value)
p.SetValue(entity, row[p.Name], null);
});
entities.Add(entity);
}
return entities;
}
catch (Exception)
{
throw;
}
}
}

关乎ToEntities扩展方法的备注:这个方法适合的是DataTable是由数据库直接返回的情况。如果DataTable数据是由Xml文件直接反序列化而来。就要在初始化DataTable时候,对DaTable的列对应在数据实体中的类型进行指定。

关于DataTable数据是直接从文件而来的备注:

public class XmlHelper
{
/// <summary> /// 将XML转换为DATATABLE /// </summary> /// <param name="FileURL"></param> /// <returns></returns> public static DataTable XmlAnalysisArray(string filepath)
{ try
{ DataSet ds = new DataSet(); ds.ReadXml(filepath); return ds.Tables[]; } catch (Exception ex)
{ throw ex; } } /// <summary> /// 将DATASET 转换为 XML /// </summary> /// <param name="FileURL"></param> /// <returns></returns> public static void DatasetConversionXML(DataSet ds, string FileURL)
{ try
{
ds.WriteXml(FileURL); } catch (Exception ex)
{ throw ex;
}
} /// <summary>
/// Xml序列化
/// </summary>
/// <typeparam name="T">对象的类型</typeparam>
/// <param name="t">序列化对象实例</param>
/// <param name="filePath">文件路径</param>
public static void XmlSerializer<T>(List<T> t, string filePath)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<T>));
StreamWriter writer = new StreamWriter(filePath);
//将s对象写入到指定的IO流文件中
try
{
xmlSerializer.Serialize(writer, t);
}
catch (Exception)
{ //errr message
}
finally
{
writer.Close();
}
} /// <summary>
/// Xml反序列化
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="t">对象实例</param>
public static List<T> XmlDeserialize<T>(List<T> t, string filePath) //必须是经过同样的过程反序列化好的文件
{
XmlSerializer mySerializer = new XmlSerializer(typeof(List<T>));
FileStream myFileStream = null;
if (File.Exists(filePath)) //检查文件是否存在
{
try
{
myFileStream = new FileStream(filePath, FileMode.Open);
t = (List<T>)mySerializer.Deserialize(myFileStream);
}
catch (FileNotFoundException)
{
//File not Found
}
catch (Exception)
{
//the other error message
}
finally
{
myFileStream.Close(); }
}
return t;
} }

Xml文件是直接从DataTable序列化而成,而不是由List<T>序列化而来。

做如下调用则会抛出异常(异常处理已经加上,谢谢Mainz)

 var dt = XmlHelper.XmlAnalysisArray(Server.MapPath(@"XML\Students"));
var list= dt.ToEntities<Student>();

调试会发现。StudentID在实体中是Int32类型。而反序列化出来的是String类型。关于此处的完美解决方案,希望大家能够指点。此处美中不足。

代码下载

反射小应用之DataTable和List<T>互操作的更多相关文章

  1. 反射类属性生成DataTable

    public class People //类名 { private static string name; //字段 private string sex;//字段 public string Se ...

  2. 【小知识】DataTable 转 List -----------点滴之水,汇涓涓细流,成汪洋大海

    在大部分时候我们从ADO中得到的数据都是DataTable.DataSet数据源,然而有强迫症的同学老是喜欢折腾,硬是要把它转换为实体集合,说是DataTable效率差云云,于是乎收到了同化. 必要信 ...

  3. c# 反射小Demo

    今天看了一下C#的反射,之前一直感觉反射是一种很高大上的东东,现在才发现不过是纸老虎而以. 所谓的反射就是,只是知道一个它是一个对象不知道其中有什么字段方法属性等,而反射就是用来获取一个未知对象的字段 ...

  4. 反射List<M> To DataTable|反射IList To DataTable|反射 DataTable To List<M>

    将DataTable集合反射获取 List<M> /// <summary> /// 根据DataTable集合反射获取 List<M> /// </summ ...

  5. 用反射写自己的DataTable转为对应的Mod

    之前写过类似的方法,今天做项目的时候又遇到了,以前的代码没有保存,导致又得重新写 场景:当我们定义自己的很多模型(Mods)的时候,而数据库读取出来的却是DataSet,DataTable类型的时候, ...

  6. java反射小实例

    利用反射实现 对配置文件的更改达到更改方法的目的 文件夹目录 首先Student类中有个sleep方法 pro.properties定义了参数 最后是RelectTestMain. package c ...

  7. java反射小例子

    package com.txwsqk.reflect; public class Car { private String brand; private String color; private i ...

  8. 使用JavaScriptSerializer序列化集合、字典、数组、DataTable为JSON字符串 分类: 前端 数据格式 JSON 2014-10-30 14:08 169人阅读 评论(0) 收藏

    一.JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大 ...

  9. Python:Day25 成员修饰符、特殊成员、反射、单例

    一.成员修饰符 共有成员 私有成员,__字段名,__方法 - 无法直接访问,只能间接访问 class Foo: def __init__(self,name,age): self.name = nam ...

随机推荐

  1. GetSurfaceLevel

      if( SUCCEEDED( g_pTexture->GetSurfaceLevel( 0, &pSurface) ) )    {        pd3dDevice->Se ...

  2. 【redis】01Redis的介绍与安装部署

    单元目标: 1.NoSQL介绍 2.Redis的介绍 3.Redis适用场合 4.Redis的安装与部署 5.Redis的数据类型 6.Redis的常用命令 7.Redis的高级应用       通过 ...

  3. ZOJ 3778 Talented Chef(找规律,模拟计算,11届ACM省赛,简单)

    题目链接 2014年浙江省赛C题,当时觉得难,现在想想这题真水.. 找规律: 若   最大的那个步骤数*m-总和>=0,那么答案就是 最大的那个步骤数 . 否则  就要另加上不够的数量,具体看代 ...

  4. POJ 3228 Gold Transportation(带权并查集,好题)

    参考链接:http://www.cnblogs.com/jiaohuang/archive/2010/11/13/1876418.html 题意:地图上某些点有金子,有些点有房子,还有一些带权路径,问 ...

  5. lintcode:最大子数组II

    题目 最大子数组 II 给定一个整数数组,找出两个不重叠子数组使得它们的和最大. 每个子数组的数字在数组中的位置应该是连续的. 返回最大的和. 样例 给出数组[1, 3, -1, 2, -1, 2], ...

  6. SpringMVC学习总结(二)——DispatcherServlet详解

    摘要: DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring ...

  7. pymongo 例子

    import pymongo class dbUtil(object): def __init__(self, tablename='functional_testing'): con = pymon ...

  8. JavaScript基础精华02(函数声明,arguments对象,匿名函数,JS面向对象基础)

    函数声明 JavaScript中声明函数的方式:(无需声明返回值类型) function add(i1, i2) {             return i1 + i2;//如果不写return返回 ...

  9. 一个酷炫的,基于HTML5,Jquery和Css的全屏焦点图特效,兼容各种浏览器

    基于HTML5和CSS的焦点图特效,梅花图案的背景很有中国特色,而且还会动哦,效果超炫,推荐下载! 演示图 html代码 <!DOCTYPE html PUBLIC "-//W3C// ...

  10. CMake学习(1)---简单程序与库

    cmake是linux平台下重要的工具,可以方便的组织makefile.之前一直在windows平台下进行软件开发,在vs2010的IDE里,只要一点run程序就能跑出结果.但是程序的编译并没有那么简 ...