zoukankan      html  css  js  c++  java
  • 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不相上下。

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

  • 相关阅读:
    [Tips] uncompyle6进行python的pyc反编译
    [Tips] pip太慢,换源
    [Notes] docker build与docker file
    [Tips] 生成当前python环境的依赖
    [Tips] imagePullPolicy取值
    [Tips] docker镜像和容器导出导入
    js模块化历程
    从一个简单例子来理解js引用类型指针的工作方式
    数组去重的方法总结
    js中const,var,let区别
  • 原文地址:https://www.cnblogs.com/wyBlog117/p/4629150.html
Copyright © 2011-2022 走看看