需要绑定实体数组比如Materiel[]绑定到界面(winform/webform都有),虽然可以直接绑定数组到GridView,但排序,过滤,查找等操作在数组里不是很方便。所以想借用DataTable做数据源。
最简单的方法就是手动建一个DataTable。为每个Materiel的property建一个Column,然后指明其数据类型。建好Table之后,循环为每个Materiel创建一个新行。如果多有几个界面,虽然做起来都差不多,但代码很难重用。
另外数据都是从WebService获取,form不允许直接访问DB,所以也不能通过ADO.net获取DataTable。
经过一段时间的考量后决定见一个专用的Utility类EntityCollectionsConvert,接口为
DataTable ToDataTable(object[] entitys);
DataTable ToDataTable<T>(List<T> entitys)
实现的原理也比较简单
1.将判断entitys不为空;
2.取出entitys的所有property
3.在DataTable中为每个property添加一列(包括元素类型)
4.为每个entity添加一行。
5.自动生成单元测试,测试,添加到项目中
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
namespace WindowsFormsApplication13
{
class Class1
{
public static DataTable ToDataTable<T>(List<T> entitys)
{
//检查实体集合不能为空
if (entitys == null || entitys.Count < 1)
{
throw new Exception("需转换的集合为空");
}
//取出第一个实体的所有Propertie
Type entityType = entitys[0].GetType();
PropertyInfo[] entityProperties = entityType.GetProperties();
//生成DataTable的structure
//生产代码中,应将生成的DataTable结构Cache起来,此处略
DataTable dt = new DataTable();
for (int i = 0; i < entityProperties.Length; i++)
{
dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType);
}
//将所有entity添加到DataTable中
foreach (object entity in entitys)
{
//检查所有的的实体都为同一类型
if (entity.GetType() != entityType)
{
throw new Exception("要转换的集合元素类型不一致");
}
object[] entityValues = new object[entityProperties.Length];
for (int i = 0; i < entityProperties.Length; i++)
{
entityValues[i] = entityProperties[i].GetValue(entity, null);
}
dt.Rows.Add(entityValues);
}
return dt;
}
}
}