ORM中去除反射,添加Expression

之前接触了别人的ORM框架,感觉牛掰到不行,然后试着自己来写自己的ORM。

        最初从园子里找到其他人写的反射的例子:

复制代码
 1     List<PropertyInfo> pis = typeof(T).GetProperties().ToList<PropertyInfo>()
 2     while (dr.Read())
 3      {
 4        T model = Activator.CreateInstance<T>();
 5 
 6         foreach (PropertyInfo propertyInfo in pis)
 7         {
 8          propertyInfo.SetValue(model,dr[propertyInfo.Name], null);
 9          }
10            list.Add(model);
11        }
复制代码

         基本满足需求,但是性能和Dapper相比,完全被打趴下了啊。
         偶然发现了Expression,好吧,不试怎么知道好用?

复制代码
 1         public Action<T, IDataRecord> SetValueToEntity<T>(int index, string ProPertyName, Type FieldType)
 2         {
 3             Type datareader = typeof(IDataRecord);
 4             //获取调用方法
 5             System.Reflection.MethodInfo Method = GetMethod(FieldType, datareader);
 6             ParameterExpression e = Expression.Parameter(typeof(T), "e");
 7             ParameterExpression r = Expression.Parameter(datareader, "r");
 8             //常数表达式
 9             ConstantExpression i = Expression.Constant(index);
10             MemberExpression ep = Expression.PropertyOrField(e, ProPertyName);
11             MethodCallExpression call = Expression.Call(r, Method, i);
12             BinaryExpression assignExpression = Expression.Assign(ep, call);
13             Expression<Action<T, IDataRecord>> resultEx = Expression.Lambda<Action<T, IDataRecord>>(assignExpression, e, r);
14             Action<T, IDataRecord> result = resultEx.Compile();
15             return result;
16         }
17 
18         public static MethodInfo GetMethod(Type FieldType, Type datareader)
19         {
20             switch (FieldType.FullName)
21             {
22                 case "System.Int16":
23                     return datareader.GetMethod("GetInt16");
24 
25                 case "System.Int32":
26                     return datareader.GetMethod("GetInt32");
27 
28                 case "System.Int64":
29                     return datareader.GetMethod("GetInt64");
30 
31                 case "Double":
32                     return datareader.GetMethod("GetDouble");
33 
34                 case "System.String":
35                     return datareader.GetMethod("GetString");
36 
37                 case "Boolean":
38                     return datareader.GetMethod("GetBoolean");
39 
40                 case "Char":
41                     return datareader.GetMethod("GetChar");
42 
43                 case "System.Guid":
44                     return datareader.GetMethod("GetGuid");
45 
46                 case "Single":
47                     return datareader.GetMethod("GetFloat");
48 
49                 case "Decimal":
50                     return datareader.GetMethod("GetDecimal");
51 
52                 case "System.DateTime":
53                     return datareader.GetMethod("GetDateTime");
54                 case "System.":
55                     return datareader.GetMethod("GetDateTime");
56             }
57             return null;
58         }
59 
60  List<Action<T, IDataReader>> actionDics = new List<Action<T, IDataReader>>();
61             //数据实体类型
62             var perDic = typeof(T).GetProperties().ToDictionary(p => p.Name);
63             //生成表头
64             for (int i = 0; i < dr.FieldCount; i++)
65             {
66                 //获取列名
67                 string colName = dr.GetName(i);
68                 Type DataType = dr.GetFieldType(i);
69                 if (perDic.ContainsKey(colName))
70                 {
71                     actionDics.Add(SetValueToEntity<T>(i, colName, DataType));
72                 }
73             }
74             while (dr.Read())
75             {
76                 T objT = Activator.CreateInstance<T>();
77                 //填充属性值
78                 actionDics.ForEach(p => p.Invoke(objT, dr));
79                 list.Add(objT);
80             }
复制代码

结果还是很可人滴,和Dapper不相上下。

下篇希望可以实现增、删、改。希望园友提供下建议。

原文地址:https://www.cnblogs.com/wyBlog117/p/4629150.html