在程序中,往往会遇到一些小情况,就是数据库取出来的时候为了方便直接将数据通过存储在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. [转载]C#中int和IntPtr相互转换

    方法一. int转IntPtr int i = 12;           IntPtr p = new IntPtr(i); IntPtr转int int myi = (int)p;         ...

  2. State of Hyperparameter Selection

    State of Hyperparameter Selection DANIEL SALTIEL VIEW NOTEBOOK Historically hyperparameter determina ...

  3. Linux 终端访问 FTP 及 上传下载 文件

    今天同事问我一个问题,在Linux 下访问FTP,并将文件上传上去. 我之前一直是用WinSCP工具的. 先将文件从linux copy到windows下,然后在传到ftp上.google 一下. 方 ...

  4. uva 434

    贪心 ~ #include <cstdio> #include <cstdlib> #include <cmath> #include <map> #i ...

  5. Unity3D与iOS的交互设计<ViewController 的跳转>

    原地址:http://www.aichengxu.com/article/%CF%B5%CD%B3%D3%C5%BB%AF/28797_12.html Unity3D与iOS的交互设计<View ...

  6. Understanding and Using Servlet Filters

    Overview of How Filters Work This section provides an overview of the following topics: How the Serv ...

  7. ios 沙盒 NSCoding(相当于JAVA对象序列化) 归档 数据存储

    通过NSCoding能实现像JAVA一样能够实现对象的序列化,可以保存对象到文件里. NSCoding 跟其他存储方式略有不同,他可以存储对象 对象存储的条件是: 对象需要遵守 NSCoding 协议 ...

  8. 李洪强漫谈iOS开发[C语言-040]-switch case

    李洪强漫谈iOS开发[C语言-039]-switch case 补充:

  9. php规范

    PSR-0 自动加载 PSR-1 基本代码规范 PSR-2 代码样式 PSR-3 日志接口

  10. C# 时间函数

    DateTime dt = DateTime.Now; string str = dt.ToString("yyyy-MM-dd");//2013-09-07 str = dt.T ...