前言:
最近项目Datatable要转为List。Datatable转List大家都说好,安全。为什么好?好在哪?为什么它就安全了?为啥就要用List?
- 读数据:
Datatable使用DataAdpter.Fill方法填充。Datatable构成了Dataset。也就是数据行与数据集。Dataset对象标识数据源中数据的本地副本,本身是可以用来引用数据源。但为了担当数据管理工具。dataset要与数据源进行交互。此时就提供了DataAdapter。也就是数据访问适配器。适配了数据库和应用程序之间的隔阂。DataAdapter表示一组sql命令和一个数据库连接用于填充Dataset和更新数据源。DataApdater提供连接对象、数据读取器和命令对象。Command对象可以通过DataReader对象来检查结果。也就解释了为什么SQLHELPER类里面读取数据源的时候使用了DataReader。DataAdapter将数据一次加载到内存后便断开与数据库的连接。所以在读取大量数据时,内存也要能跟上。可以说他们之间的关系是通过DataAdapter将A的数据全部拿到B。此时B已经有了数据,自然不需要A了,所以可以和A说拜拜,但是B要考虑的就是自己有没有地方将A放下。
- 不符合面向对象:
Datatable是一个二维表。数据是看不见的。但是我们需要从里面读取某个值或修改的时候还需要结束数据库。啥啥都要看库。数据都暴露了。Datatable架空了实体类。 - 弱类型:
不能看出字段的数据类型
List:
- 读数据-性能好:
List使用DataReader进行填充。DataReader的速度更快。为什么快呢?它是一个向前的指针。不断向前读数据,且每次只读取一条,提高应用程序性能,减少系统开销。因为是能读数据,所以数据库要一直连接。是一种高效的读取数据流的方法。 - 符合面向对象:
实体类就是数据库的映射。泛型集合中的实体类与Datatable中对应,也就是实体类的属性和Datatable字段是对应的。传出去的是实体类。读数据时只需要点一下:List[0].xxxx就可以了。也就是不需要了解数据库结构。 - 避免拆箱装箱:
装箱时将值类型转换为引用类型。拆箱就是将引用类型转换为值类型 - 弱类型:
字段类型为已知。在编译时就确定好了类型。
转换:
public static class CovertListHelper
{
/// <summary>
/// 将DataTable转化成List[T],要求T是一个引用类型,可实例化类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dt"></param>
/// <returns></returns>
public static List<T> convertToList<T>(DataTable dt) where T : new()
{
//定义一个list集合-ts
List<T> ts = new List<T>();
//获取T的类型
Type type = typeof(T);
//定义一个临时的变量
string tempName = "";
//遍历里面DataTable的行
foreach (DataRow dr in dt.Rows)
{
//先定义一个T-t
T t = new T();
//接收t的公共属性,PropertyInfo是发现属性的属性和提供对属性元数据的访问的
PropertyInfo[] propertys = t.GetType().GetProperties();
//遍历所有的属性
foreach (PropertyInfo pi in propertys)
{
//临时变量获得属性值
tempName = pi.Name;
//如果这一行里面含有这个属性
if (dt.Columns.Contains(tempName))
{
//如果该属性不可写,那么直接跳过本次循环
if (!pi.CanWrite) continue;
//让value获取临时变量的这个属性所对应的值
object value = dr[tempName];
//如果不是不存在的值
if (value != DBNull.Value)
{
//用索引化属性的可选索引值设置指定对象的该属性值
pi.SetValue(t, value, null);
}
}
}
//把对象添加到泛型ts里面
ts.Add(t);
}
//返回泛型
return ts;
}
}`在这里插入代码片`