在最近做的一个案子里,需要绑定实体数组比如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.自动生成单元测试,测试,添加到项目中
- 1 public static DataTable ToDataTable<T>(List<T> entitys)
- 2 {
- 3
- 4 //检查实体集合不能为空
- 5 if (entitys ==null|| entitys.Count<1)
- 6 {
- 7 throw new Exception("需转换的集合为空");
- 8 }
- 9
- 10 //取出第一个实体的所有Propertie
- 11 Type entityType= entitys[0].GetType();
- 12 PropertyInfo[] entityProperties= entityType.GetProperties();
- 13
- 14 //生成DataTable的structure
- 15 //生产代码中,应将生成的DataTable结构Cache起来,此处略
- 16 DataTable dt = new DataTable();
- 17 for (int i = 0; i < entityProperties.Length; i++)
- 18 {
- 19 dt.Columns.Add(entityProperties[i].Name,entityProperties[i].PropertyType);
- 20 }
- 21
- 22 //将所有entity添加到DataTable中
- 23 foreach (object entity in entitys)
- 24 {
- 25 //检查所有的的实体都为同一类型
- 26 if (entity.GetType()!=entityType)
- 27 {
- 28 throw new Exception("要转换的集合元素类型不一致");
- 29 }
- 30 object[] entityValues = new object[entityProperties.Length];
- 31 for (int i = 0; i < entityProperties.Length; i++)
- 32 {
- 33 entityValues[i] = entityProperties[i].GetValue(entity, null);
- 34
- 35 }
- 36 dt.Rows.Add(entityValues);
- 37 }
- 38 return dt;
- 39 }