你的位置:首页 > ASP.net教程

[ASP.net教程]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不相上下。

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