• 通过表达式树把datareader和datatable转换为实体


         续上两篇文章,使用emit构造dynamic method,把 datareader转换为实体,以避免直接使用反射来实现带来的性能损失。代码看似没有纰漏,但是实际上我在framwork4下运行时,调用 dynamic method时,

    系统都会报 “ 找不到方法 ‘?’  ”的错误,没有找到问题所在,网上查了下资料,发现在framwork3.5以上还可以用表达式树动态构造 执行的语句,并动态编译成方法。性能上与emit还是接近,,而且代码精简了许多。

    废话不多说,上代码

     public class EntityConverter
        {
            public static Action<T, object> GetSetter<T>(PropertyInfo  property)
            {
                Action<T, object> result = null;
                Type type = typeof(T);           
                string key = type.AssemblyQualifiedName + "_set_" + property.Name;
                if (HttpRuntime.Cache.Get(key) == null)
                {
    
                    //创建 对实体 属性赋值的expression
                    ParameterExpression parameter = Expression.Parameter(type, "t");
                    ParameterExpression value = Expression.Parameter(typeof(object), "propertyValue");
                    MethodInfo setter = type.GetMethod("set_" + property.Name);
                    MethodCallExpression call = Expression.Call(parameter, setter, Expression.Convert(value, property.PropertyType));
                    var lambda = Expression.Lambda<Action<T, object>>(call, parameter, value);
                    result = lambda.Compile();
                    HttpRuntime.Cache[key] = result;
                }
                else
                {
                    result =  HttpRuntime.Cache[key] as Action<T, object>;
                }        
                 return result;
            }
    
            public static List<T> ToList<T>(DataTable dt) where T : new()
            {
                List<T> list = new List<T>();
                if (dt == null || dt.Rows.Count == 0)
                {
                    return list;
                }   
    
                foreach (DataRow dr in dt.Rows)
                {
                    T t= new T();
                    foreach (PropertyInfo prop in typeof(T).GetProperties())
                    {
                        if (dr.Table.Columns.Contains(prop.Name))
                        {
                            GetSetter<T>(prop)(t, dr[prop.Name]);
                        }
                    }
                    list.Add(t);
                }       
    
                return list;
            }
    
            public static List<T> ToList<T>(IDataReader dr) where T:new()
            {
                List<T> list = new List<T>();        
                while (dr.Read())
                {
                    T t = new T();
                    foreach (PropertyInfo prop in typeof(T).GetProperties())
                    {                 
                            GetSetter<T>(prop)(t, dr[prop.Name]);                
                    }
                    list.Add(t);
                }
                return list;
            }
    
        }
    

      

    代码还稍微有点粗糙,还可以细化一下,比如 datatable和datareader的字段名称,和对应实体的属性名,可以忽略大小写,目前我的代码是区分的,有兴趣的可以自己优化。

    如果你看完了我写的文字还代码,还是一头雾水,可以看看我的上两篇博文。简单说 就是类似orm的核心功能,把通过ado.net组件查询到的数据(datatable,datareader)转换为实体列表 List<T>,

    如果你的代码框架还比较古老,又不愿意引入诸如EF,Nhibernate那样的比较大的框架,不妨考虑自己写一个这样的简单的方法。

               List<T> list;
    using (IDataReader dr = sqlCommand.ExecuteReader(sql) { list = EntityConverter.ToList<T>(dr); }
  • 相关阅读:
    作图与修图
    stringR包 字符串拼接,对字符串切分 替换 匹配提取 位置提取
    ggplot tools ggpubr arrange
    R 处理、可视化 多变量数据
    R 列表
    GATK jointcalling 不需要手动设置ploidy
    rsync 本地路径到挂盘路径 ;挂盘路径到本地
    linux 帐号便捷登陆
    科研路上,能往前走,就往前走,不犯完美主义错误, 警惕常见读博误区
    R 矩阵数组
  • 原文地址:https://www.cnblogs.com/lindping/p/7545208.html
Copyright © 2020-2023  润新知