C ා the reflection string is converted to entity class and used as parameter in the generic method

There is such a requirement in the work, there are N different reports, each report corresponds to a data source. Previously, SQL statistical method was used, and the statistical data was in memory. First, the entity corresponding to the data source was defined in. The statistical conditions are implemented by the expression of lamdba, and the cells are defined by tools. In the process of implementation, it's very Low to write data retrieval display for each table. The definition of retrieval conditions is regular. Statistical implementation is a piece of C ා code. However, it can be realized through generics and reflection according to different data sources, i.e. different list < entity >.

Get entity type from string

 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 }

 

Generic method definition

1 public XXDataMemory BuildDataMemoryPattern<T>(XXParams zb, string id) where T : XXDataRecord, new()

 

Call method code

 1 var obj = new GenerateDataHelper(_Param);
 2 Type myGenericClassType = obj.GetType();
 3 //MakeGenericMethod Set generic parameter type
 4 MethodInfo mi = myGenericClassType.GetMethod("BuildDataMemoryPattern").MakeGenericMethod(typeEntity);
 5 int count = 0;
 6 //Set call method parameters
 7 object[] invokeArgs = new object[] { zb, id, count };
 8 //call
 9 var dt = (DataTable)mi.Invoke(obj, invokeArgs);
10 //Access to return data
11 recordCount = (int)invokeArgs[9];

 

The following is all the code. The specific function implementation is omitted

 1 public class UtilFetchHelper 
 2 {
 3     //Get entity type
 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         //Get entity name based on the passed in parameter
36         var entityName = GetDataSourceEntityName(zb);
37         //Get entity type
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         //Get return data here
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         //The following is the specific implementation code for DataList Query operation
84     }
85 }

Tags: C# SQL

Posted on Sun, 09 Feb 2020 10:24:13 -0500 by shalinik