反射小应用之DataTable和List<T>互操作
在程序中,往往会遇到一些小情况,就是数据库取出来的时候为了方便直接将数据通过存储在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>互操作的更多相关文章
- 反射类属性生成DataTable
public class People //类名 { private static string name; //字段 private string sex;//字段 public string Se ...
- 【小知识】DataTable 转 List -----------点滴之水,汇涓涓细流,成汪洋大海
在大部分时候我们从ADO中得到的数据都是DataTable.DataSet数据源,然而有强迫症的同学老是喜欢折腾,硬是要把它转换为实体集合,说是DataTable效率差云云,于是乎收到了同化. 必要信 ...
- c# 反射小Demo
今天看了一下C#的反射,之前一直感觉反射是一种很高大上的东东,现在才发现不过是纸老虎而以. 所谓的反射就是,只是知道一个它是一个对象不知道其中有什么字段方法属性等,而反射就是用来获取一个未知对象的字段 ...
- 反射List<M> To DataTable|反射IList To DataTable|反射 DataTable To List<M>
将DataTable集合反射获取 List<M> /// <summary> /// 根据DataTable集合反射获取 List<M> /// </summ ...
- 用反射写自己的DataTable转为对应的Mod
之前写过类似的方法,今天做项目的时候又遇到了,以前的代码没有保存,导致又得重新写 场景:当我们定义自己的很多模型(Mods)的时候,而数据库读取出来的却是DataSet,DataTable类型的时候, ...
- java反射小实例
利用反射实现 对配置文件的更改达到更改方法的目的 文件夹目录 首先Student类中有个sleep方法 pro.properties定义了参数 最后是RelectTestMain. package c ...
- java反射小例子
package com.txwsqk.reflect; public class Car { private String brand; private String color; private i ...
- 使用JavaScriptSerializer序列化集合、字典、数组、DataTable为JSON字符串 分类: 前端 数据格式 JSON 2014-10-30 14:08 169人阅读 评论(0) 收藏
一.JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大 ...
- Python:Day25 成员修饰符、特殊成员、反射、单例
一.成员修饰符 共有成员 私有成员,__字段名,__方法 - 无法直接访问,只能间接访问 class Foo: def __init__(self,name,age): self.name = nam ...
随机推荐
- CString向char类型转化 ---“=”: 无法从“wchar_t *”转换为“char *
此文从网上复制过来,原文出处已丢失,望见谅哈 VC 2005中,这个本来很简单的问题又稍微复杂了一点. 在工程里面,一个必不可少的步骤就是把CString转换为shar*字符串.通过 ...
- OWASP
开放式Web应用程序安全项目(OWASP,Open Web Application Security Project)是一个组织,它提供有关计算机和互联网应用程序的公正.实际.有成本效益的信息.其目的 ...
- java poi导入EXCEL xls文件代码
/** * */ package com.bn.car.common.report.excel; import java.io.FileInputStream; import java.io.IOEx ...
- mysql数据库主外键级联删除脚本RESTRICT --> CASCADE
在项目中,我们一般在数据库设计的时候做主外键关联设计,要么就不做.但是这样不符合规范,呵呵. 建立主外键关系的时候,默认是不能级联删除的.而出现往往在删除主表的数据时报错, 需要先删除从表然后再删除主 ...
- zju 1037 Gridland(找规律,水题)
题目链接 多写几个案例,根据数据的奇偶性,就能找到规律了 #include<stdio.h> int main() { int t,n,m; double ans; scanf(" ...
- Android中自定义Checkbox
custom_checkbox.xml文件: <?xml version="1.0" encoding="utf-8"?> <selector ...
- *[hackerrank]Volleyball Match
https://www.hackerrank.com/contests/w1/challenges/volleyball-match 此题不错,首先可以看出是DP,S(x, y)= S(x - 1, ...
- SqlDBHelper常用方法
/*============================================================= *.net连接数据库常用方法 *Author : dongny,Li * ...
- float和decimal执行效率 (只是代码 没有分析—)
float版: public static void getSmallFramPoint() { string framString ="Row,"+"Colum,&qu ...
- 获取腾讯soso地图坐标代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
代码下载