之前接触了别人的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不相上下。
下篇希望可以实现增、删、改。希望园友提供下建议。
原标题:ORM中去除反射,添加Expression
关键词:反射