工作中有这样一个需求,有N张不同的报表,每张报表对应一个数据源,统计数据采用内存方式,首先在内在里定义了数据源对应实体。统计条件用lamdba表达式式实现,通过工具对单元格进行定义。在实现过程中针对每一张表来写取数显示是很Low的了,取数条件定义都是规则的,统计实现就是一段C#代码,但是要针对不同的数据源也就是不同的List<Entity>,通过研究发现通过泛型和反射可以实现。
根据字符串获取实体类型
1 private Type getEntity(string typeName) 2 { 3 var workPath = AppDomain.CurrentDomain.BaseDirectory; 4 string[] files = Directory.GetFiles(workPath, "XXX.Utils.dll", SearchOption.TopDirectoryOnly); 5 foreach (string file in files) 6 { 7 string ext = file.Substring(file.LastIndexOf(".")); 8 if (ext != ".dll") continue; 9 try 10 { 11 Assembly asm = Assembly.LoadFile(file); 12 Type[] allTypes = asm.GetTypes(); 13 foreach (Type t in allTypes) 14 { 15 if (t.IsSubclassOf(typeof(XXDataRecord))) 16 { 17 if (t.Name.ToUpper().IsSame(typeName.ToUpper())) 18 return t; 19 } 20 } 21 } 22 catch 23 { 24 return null; 25 } 26 } 27 return null; 28 }
泛型方法定义
1 public XXDataMemory BuildDataMemoryPattern<T>(XXParams zb, string id) where T : XXDataRecord, new()
调用方法代码
1 var obj = new GenerateDataHelper(_Param); 2 Type myGenericClassType = obj.GetType(); 3 //MakeGenericMethod 设置泛型参数类型 4 MethodInfo mi = myGenericClassType.GetMethod("BuildDataMemoryPattern").MakeGenericMethod(typeEntity); 5 int count = 0; 6 //设置调用方法参数 7 object[] invokeArgs = new object[] { zb, id, count }; 8 //调用 9 var dt = (DataTable)mi.Invoke(obj, invokeArgs); 10 //获取回返数据 11 recordCount = (int)invokeArgs[9];
下面是全部代码,具体功能实现略过
1 public class UtilFetchHelper 2 { 3 //获取实体类型 4 private Type getEntity(string typeName) 5 { 6 var workPath = AppDomain.CurrentDomain.BaseDirectory; 7 string[] files = Directory.GetFiles(workPath, "XXX.Utils.dll", SearchOption.TopDirectoryOnly); 8 foreach (string file in files) 9 { 10 string ext = file.Substring(file.LastIndexOf(".")); 11 if (ext != ".dll") continue; 12 try 13 { 14 Assembly asm = Assembly.LoadFile(file); 15 Type[] allTypes = asm.GetTypes(); 16 foreach (Type t in allTypes) 17 { 18 if (t.IsSubclassOf(typeof(XXDataRecord))) 19 { 20 if (t.Name.ToUpper().IsSame(typeName.ToUpper())) 21 return t; 22 } 23 } 24 } 25 catch 26 { 27 return null; 28 } 29 } 30 return null; 31 } 32 33 public DataTable BuildDataMemoryPattern(XXParams zb, string id, out int recordCount) 34 { 35 //根据传入参数获取实体名称 36 var entityName = GetDataSourceEntityName(zb); 37 //获取实体类型 38 Type typeEntity = getEntity(entityName); 39 if (typeEntity == null) 40 return null; 41 var obj = new GenerateDataHelper(_Param); 42 Type myGenericClassType = obj.GetType(); 43 MethodInfo mi = myGenericClassType.GetMethod("BuildDataMemoryPattern").MakeGenericMethod(typeEntity); 44 int count = 0; 45 object[] invokeArgs = new object[] { zb, id, count }; 46 var dt = (DataTable)mi.Invoke(obj, invokeArgs); 47 //这里获取回返数据 48 recordCount = (int)invokeArgs[9]; 49 return dt; 50 } 51 } 52 53 public class GenerateDataHelper 54 { 55 private List<XXDataRecord> _DataList; 56 private List<XXDataRecord> DataList 57 { 58 set { _DataList = value; } 59 get { return _DataList; } 60 } 61 62 private List<T> GetDataSource<T>() where T : XXDataRecord, new() 63 { 64 var _DataList = new List<T>(); 65 var dt = DB.ExecuteDataTable("Select * From XX"); 66 for (int i = 0; i < dt.Rows.Count; i++) 67 { 68 var dataEnt = new T(); 69 for (int j = 0; j < dt.Columns.Count; j++) 70 { 71 dataEnt[dt.Columns[j].ColumnName] = dt.Rows[i][j]; 72 } 73 _DataList.Add(dataEnt); 74 } 75 return _DataList; 76 } 77 78 79 public XXDataMemory BuildDataMemoryPattern<T>(XXParams zb, string id) where T : XXDataRecord, new() 80 { 81 List<T> DataList = new List<T>(); 82 DataList = GetDataSource<T>(); 83 //以下是具体实现代码 针对DataList查询操作 84 } 85 }